summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTizenOpenSource <tizenopensrc@samsung.com>2023-01-20 12:37:41 +0900
committerTizenOpenSource <tizenopensrc@samsung.com>2023-01-20 12:37:41 +0900
commitdb71814a6f682fbcff68240df67fb64a6c986516 (patch)
tree3a367c788b474e85251fc74f80f899074858c742
parent35ba6f0ff982060c9bc1fe9868092380d302646b (diff)
downloaded-db71814a6f682fbcff68240df67fb64a6c986516.tar.gz
ed-db71814a6f682fbcff68240df67fb64a6c986516.tar.bz2
ed-db71814a6f682fbcff68240df67fb64a6c986516.zip
Imported Upstream version 1.19upstream/1.19upstream
-rw-r--r--AUTHORS4
-rw-r--r--ChangeLog31
-rw-r--r--INSTALL14
-rw-r--r--Makefile.in2
-rw-r--r--NEWS49
-rw-r--r--README12
-rw-r--r--buffer.c8
-rw-r--r--carg_parser.c2
-rw-r--r--carg_parser.h2
-rwxr-xr-xconfigure17
-rw-r--r--doc/ed.121
-rw-r--r--doc/ed.info127
-rw-r--r--doc/ed.texi220
-rw-r--r--ed.h7
-rw-r--r--global.c6
-rw-r--r--io.c46
-rw-r--r--main.c46
-rw-r--r--main_loop.c86
-rw-r--r--regex.c4
-rw-r--r--signal.c23
-rw-r--r--testsuite/a.ed4
-rw-r--r--testsuite/a.r1
-rwxr-xr-xtestsuite/check.sh2
-rw-r--r--testsuite/filter.ed6
-rw-r--r--testsuite/filter.r13
-rw-r--r--testsuite/g.ed4
-rw-r--r--testsuite/g.r6
-rw-r--r--testsuite/w.ed7
-rw-r--r--testsuite/w.r1
29 files changed, 408 insertions, 363 deletions
diff --git a/AUTHORS b/AUTHORS
index 26c3a0f..5a6d9b4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -3,8 +3,8 @@ Since 2006 GNU ed is maintained by Antonio Diaz Diaz.
Before version 0.3, GNU ed and its man page were written and maintained
(sic) by Andrew L. Moore.
-The original info page and GNUification of the code were graciously
-provided by François Pinard.
+The original info page and GNUification of the code were graciously provided
+by François Pinard.
-------------------
diff --git a/ChangeLog b/ChangeLog
index 96314b6..4dc0df9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2023-01-11 Antonio Diaz Diaz <antonio@gnu.org>
+
+ * Version 1.19 released.
+ * main_loop.c (exec_command): Fix commands 'e', 'E'; they did set
+ the 'modified' flag if file not found. (Reported by Harry Graf).
+ (main_loop): Print script error line to stdout instead of stderr.
+ * Change long name of option '-s' to '--script'.
+ (Suggested by Andrew L. Moore).
+ * Assign short name '-q' to options '--quiet' and '--silent'.
+ * main.c (show_strerror) Use '!quiet' to enable diagnostics.
+ * Do not process file names for backslash escapes.
+ (Suggested by Andrew L. Moore).
+ * ed.texi: Document 0 as starting point for searches '0;/RE/'.
+ Document how to achieve the effect of ex style '!' filtering.
+
2022-02-04 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.18 released.
@@ -283,7 +298,7 @@
* Remove all global variables.
* ed.texinfo: Add the changes from Andrew and some mine.
-Sun Jun 26 22:21:59 1994 Andrew Moore <alm@worm.talke.org>
+Sun Jun 26 22:21:59 1994 Andrew L. Moore <alm@worm.talke.org>
* GNU ed 0.2 release.
@@ -301,27 +316,27 @@ Sun Jun 26 22:21:59 1994 Andrew Moore <alm@worm.talke.org>
* Capitilize error messages per the standard.
-Wed Jun 22 01:06:11 1994 Andrew Moore <alm@woops.talke.org>
+Wed Jun 22 01:06:11 1994 Andrew L. Moore <alm@woops.talke.org>
* ed.h: Generic definition of INT_MAX <bson@ai.mit.edu>
* signal.c: Added #ifndef SIG_ERR <assar@stacken.kth.se>
-Tue Apr 19 10:52:51 1994 Andrew Moore <alm@woops.talke.org>
+Tue Apr 19 10:52:51 1994 Andrew L. Moore <alm@woops.talke.org>
* Version 0.1. Initial release for GNU.
* main.c (exec_command): Add comment command '#'.
-Mon Mar 21 21:58:11 PST 1994 Andrew Moore <alm@netcom.com>
+Mon Mar 21 21:58:11 PST 1994 Andrew L. Moore <alm@netcom.com>
* Use umask 077 to open buffer file.
-Sat Mar 19 14:06:52 PST 1994 Andrew Moore <alm@netcom.com>
+Sat Mar 19 14:06:52 PST 1994 Andrew L. Moore <alm@netcom.com>
* Removed problematic DES and insque support.
-Wed Jan 19 20:42:50 PST 1994 Andrew Moore <alm@netcom.com>
+Wed Jan 19 20:42:50 PST 1994 Andrew L. Moore <alm@netcom.com>
* Added reliable signal(2) for SysV.
@@ -331,8 +346,8 @@ Dec 1993 François Pinard <pinard@icule>
Copyright (C) 1993 François Pinard
-Copyright (C) 1994 Andrew Moore
-Copyright (C) 2006-2022 Antonio Diaz Diaz.
+Copyright (C) 1994 Andrew L. Moore
+Copyright (C) 2006-2023 Antonio Diaz Diaz.
This file is a collection of facts, and thus it is not copyrightable,
but just in case, you have unlimited permission to copy, distribute, and
diff --git a/INSTALL b/INSTALL
index e696e85..dd7947f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
Requirements
------------
-You will need a C89 compiler and a C library compatible with POSIX.
-(gcc 3.3.6 or newer is recommended).
+You will need a C89 compiler with support for declaration-after-statement
+and a C library compatible with POSIX. (gcc 3.3.6 or newer is recommended).
I use gcc 6.1.0 and 3.3.6, but the code should compile with any standards
compliant compiler.
Gcc is available at http://gcc.gnu.org.
@@ -15,8 +15,8 @@ Procedure
or
lzip -cd ed[version].tar.lz | tar -xf -
-This creates the directory ./ed[version] containing the source from
-the main archive.
+This creates the directory ./ed[version] containing the source code
+extracted from the archive.
2. Change to ed directory and run configure.
(Try 'configure --help' for usage instructions).
@@ -51,15 +51,15 @@ object files and executables to go and run the 'configure' script.
'configure' automatically checks for the source code in '.', in '..', and
in the directory that 'configure' is in.
-'configure' recognizes the option '--srcdir=DIR' to control where to
-look for the sources. Usually 'configure' can determine that directory
+'configure' recognizes the option '--srcdir=DIR' to control where to look
+for the source code. Usually 'configure' can determine that directory
automatically.
After running 'configure', you can run 'make' and 'make install' as
explained above.
-Copyright (C) 2006-2022 Antonio Diaz Diaz.
+Copyright (C) 2006-2023 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
distribute, and modify it.
diff --git a/Makefile.in b/Makefile.in
index f716df4..ec12ed1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -42,7 +42,7 @@ doc : info man
info : $(VPATH)/doc/$(pkgname).info
$(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texi
- cd $(VPATH)/doc && makeinfo $(pkgname).texi
+ cd $(VPATH)/doc && $(MAKEINFO) $(pkgname).texi
man : $(VPATH)/doc/$(progname).1
diff --git a/NEWS b/NEWS
index b1ba354..3a542bf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,36 +1,27 @@
-Changes in version 1.18:
+Changes in version 1.19:
-The shell escape command (!) now flushes stdout so that the modified command
-is always printed before being executed even if standard output is fully
-buffered (for example, a file). (Reported by Sören Tempel).
+Reading a non-existent file with commands 'e' or 'E' did set the 'modified'
+flag, which prevented a following 'e' command from succeeding.
+(Reported by Harry Graf).
-A couple of harmless memory leaks have been fixed. (They both happened just
-before ed exits). (Reported by Xosé Vázquez Pérez).
+The long name of option '-s' has been changed to '--script'.
+Option '-s' now only suppresses byte counts and the '!' prompt as mandated
+by POSIX. It no longer suppresses diagnostic messages written to stderr.
+(Both changes suggested by Andrew L. Moore).
-The pointer returned by the function 'strip_escapes' is now checked. (It may
-be null if memory is exhausted).
+The short name '-q' has been assigned to options '--quiet' and '--silent'.
+Option '-q' now only suppresses diagnostic messages written to stderr.
-The shell escape command (!) now removes the backslash from each escaped '%'
-character within the text of the shell command line.
-(Reported by Martin Thomsen).
+The help message showing the line where a script error happened when ed's
+input is from a regular file is now printed to stdout instead of stderr
+because it is enabled by the 'H' command.
-Case-insensitive regular expressions have been implemented as in GNU sed.
+Ed no longer processes file names for backslash escapes.
+(Suggested by Andrew L. Moore).
-Syntax errors in regular expressions, for example unmatched ( or \(, no
-longer overwrite a previously compiled regular expression, preventing a
-"No previous pattern" error.
+It has been documented in the manual that address 0 is valid as a starting
+point for searches so that '0;/RE/' can match the regular expression RE in
+the first line of the buffer.
-The option '--strip-trailing-cr', which removes carriage returns at end of
-text lines, has been added.
-
-Loading a file now fails if a line is longer than INT_MAX bytes or if the
-file contains more than INT_MAX lines (usually 2 Gi lines). (Instead of
-overflowing line addresses).
-
-In interactive mode ed now sets final exit status to 1 if a fatal error
-happens while reading the file passed in the command line.
-
-red now reports "Directory access restricted" instead of "Invalid filename"
-when trying to edit a file outside of the current directory.
-
-The new chapter "The 's' Command" has been added to the manual.
+It has been documented in the manual how to achieve the effect of ex style
+'!' filtering with a sequence of commands.
diff --git a/README b/README
index a858b83..e24e0fb 100644
--- a/README
+++ b/README
@@ -59,17 +59,11 @@ EXTENSIONS
* 'z' for scrolling through the buffer.
* The POSIX interactive global commands 'G' and 'V' are extended to
- support multiple commands, including 'a', 'i' and 'c'. The command
+ support multiple commands, including 'a', 'c', and 'i'. The command
format is the same as for the global commands 'g' and 'v', i.e., one
command per line with each line, except for the last, ending in a
backslash (\).
- * The file commands 'E', 'e', 'r', 'W' and 'w' process a <file>
- argument for backslash escapes; i.e., any character preceded by a
- backslash is interpreted literally. If the first character of a <file>
- argument is a bang (!), then the rest of the line is interpreted as a
- shell command, and no escape processing is performed by GNU ed.
-
* For SunOS ed(1) compatibility, GNU ed runs in restricted mode if invoked
as red. This limits editing of files in the local directory only and
prohibits shell commands.
@@ -123,8 +117,8 @@ or:
*** Output u.o of script u.ed is incorrect ***
-Copyright (C) 1993, 1994 Andrew Moore
-Copyright (C) 2006-2022 Antonio Diaz Diaz.
+Copyright (C) 1993, 1994 Andrew L. Moore
+Copyright (C) 2006-2023 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
distribute, and modify it.
diff --git a/buffer.c b/buffer.c
index a5031e6..12c3e99 100644
--- a/buffer.c
+++ b/buffer.c
@@ -1,7 +1,7 @@
/* buffer.c: scratch-file buffer routines for the ed line editor. */
/* GNU ed - The GNU line editor.
- Copyright (C) 1993, 1994 Andrew Moore, Talke Studio
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 1993, 1994 Andrew L. Moore, Talke Studio
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -79,7 +79,7 @@ static void insert_node( line_t * const lp, line_t * const prev )
/* to be called before add_line_node */
static bool too_many_lines( void )
{
- if( last_addr_ < INT_MAX - 1 ) return false;
+ if( last_addr_ < INT_MAX - 2 ) return false;
set_error_msg( "Too many lines in buffer" ); return true;
}
@@ -594,7 +594,7 @@ undo_t * push_undo_atom( const int type, const int from, const int to )
{ set_error_msg( "Undo stack too long" );
free_undo_stack(); enable_interrupts(); return 0; }
const int new_size = ( ( min_size < 512 ) ? 512 :
- ( min_size > INT_MAX / 2 ) ? INT_MAX : ( min_size / 512 ) * 1024 );
+ ( min_size >= INT_MAX / 2 ) ? INT_MAX - 1 : ( min_size / 512 ) * 1024 );
void * new_buf = 0;
if( ustack ) new_buf = realloc( ustack, new_size );
else new_buf = malloc( new_size );
diff --git a/carg_parser.c b/carg_parser.c
index 181ba23..2b65bac 100644
--- a/carg_parser.c
+++ b/carg_parser.c
@@ -1,5 +1,5 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided
diff --git a/carg_parser.h b/carg_parser.h
index 0c64861..52c5247 100644
--- a/carg_parser.h
+++ b/carg_parser.h
@@ -1,5 +1,5 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This library is free software. Redistribution and use in source and
binary forms, with or without modification, are permitted provided
diff --git a/configure b/configure
index 3531bcd..5692ef9 100755
--- a/configure
+++ b/configure
@@ -1,12 +1,12 @@
#! /bin/sh
# configure script for GNU ed - The GNU line editor
-# Copyright (C) 2006-2022 Antonio Diaz Diaz.
+# Copyright (C) 2006-2023 Antonio Diaz Diaz.
#
# This configure script is free software: you have unlimited permission
# to copy, distribute, and modify it.
pkgname=ed
-pkgversion=1.18
+pkgversion=1.19
progname=ed
srctrigger=doc/${pkgname}.texi
@@ -25,6 +25,7 @@ CC=gcc
CPPFLAGS=
CFLAGS='-Wall -W -O2'
LDFLAGS=
+MAKEINFO=makeinfo
# checking whether we are using GNU C.
/bin/sh -c "${CC} --version" > /dev/null 2>&1 || { CC=cc ; CFLAGS=-O2 ; }
@@ -58,7 +59,7 @@ while [ $# != 0 ] ; do
echo "Options and variables: [defaults in brackets]"
echo " -h, --help display this help and exit"
echo " -V, --version output version information and exit"
- echo " --srcdir=DIR find the sources in DIR [. or ..]"
+ echo " --srcdir=DIR find the source code in DIR [. or ..]"
echo " --prefix=DIR install into DIR [${prefix}]"
echo " --exec-prefix=DIR base directory for arch-dependent files [${exec_prefix}]"
echo " --bindir=DIR user executables directory [${bindir}]"
@@ -71,6 +72,7 @@ while [ $# != 0 ] ; do
echo " CFLAGS=OPTIONS command line options for the C compiler [${CFLAGS}]"
echo " CFLAGS+=OPTIONS append options to the current value of CFLAGS"
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
+ echo " MAKEINFO=NAME makeinfo program to use [${MAKEINFO}]"
echo
exit 0 ;;
--version | -V)
@@ -100,6 +102,7 @@ while [ $# != 0 ] ; do
CFLAGS=*) CFLAGS=${optarg} ;;
CFLAGS+=*) CFLAGS="${CFLAGS} ${optarg}" ;;
LDFLAGS=*) LDFLAGS=${optarg} ;;
+ MAKEINFO=*) MAKEINFO=${optarg} ;;
--*)
echo "configure: WARNING: unrecognized option: '${option}'" 1>&2 ;;
@@ -119,7 +122,7 @@ while [ $# != 0 ] ; do
fi
done
-# Find the source files, if location was not specified.
+# Find the source code, if location was not specified.
srcdirtext=
if [ -z "${srcdir}" ] ; then
srcdirtext="or . or .." ; srcdir=.
@@ -131,7 +134,7 @@ if [ -z "${srcdir}" ] ; then
fi
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
- echo "configure: Can't find sources in ${srcdir} ${srcdirtext}" 1>&2
+ echo "configure: Can't find source code in ${srcdir} ${srcdirtext}" 1>&2
echo "configure: (At least ${srctrigger} is missing)." 1>&2
exit 1
fi
@@ -169,10 +172,11 @@ echo "CC = ${CC}"
echo "CPPFLAGS = ${CPPFLAGS}"
echo "CFLAGS = ${CFLAGS}"
echo "LDFLAGS = ${LDFLAGS}"
+echo "MAKEINFO = ${MAKEINFO}"
rm -f Makefile
cat > Makefile << EOF
# Makefile for GNU ed - The GNU line editor
-# Copyright (C) 2006-2022 Antonio Diaz Diaz.
+# Copyright (C) 2006-2023 Antonio Diaz Diaz.
# This file was generated automatically by configure. Don't edit.
#
# This Makefile is free software: you have unlimited permission
@@ -193,6 +197,7 @@ CC = ${CC}
CPPFLAGS = ${CPPFLAGS}
CFLAGS = ${CFLAGS}
LDFLAGS = ${LDFLAGS}
+MAKEINFO = ${MAKEINFO}
EOF
cat "${srcdir}/Makefile.in" >> Makefile
diff --git a/doc/ed.1 b/doc/ed.1
index 73ead67..3a84bdf 100644
--- a/doc/ed.1
+++ b/doc/ed.1
@@ -1,5 +1,5 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
-.TH ED "1" "February 2022" "GNU ed 1.18" "User Commands"
+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
+.TH ED "1" "January 2023" "GNU ed 1.19" "User Commands"
.SH NAME
ed \- line-oriented text editor
.SH SYNOPSIS
@@ -33,11 +33,14 @@ exit with 0 status even if a command fails
\fB\-p\fR, \fB\-\-prompt\fR=\fI\,STRING\/\fR
use STRING as an interactive prompt
.TP
+\fB\-q\fR, \fB\-\-quiet\fR, \fB\-\-silent\fR
+suppress diagnostics written to stderr
+.TP
\fB\-r\fR, \fB\-\-restricted\fR
run in restricted mode
.TP
-\fB\-s\fR, \fB\-\-quiet\fR, \fB\-\-silent\fR
-suppress diagnostics, byte counts and '!' prompt
+\fB\-s\fR, \fB\-\-script\fR
+suppress byte counts and '!' prompt
.TP
\fB\-v\fR, \fB\-\-verbose\fR
be verbose; equivalent to the 'H' command
@@ -48,10 +51,10 @@ strip carriage returns at end of text lines
Start edit by reading in 'file' if given.
If 'file' begins with a '!', read output of shell command.
.PP
-Exit status: 0 for a normal exit, 1 for environmental problems (file
-not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or
-invalid input file, 3 for an internal consistency error (e.g., bug) which
-caused ed to panic.
+Exit status: 0 for a normal exit, 1 for environmental problems
+(file not found, invalid command line options, I/O errors, etc), 2 to
+indicate a corrupt or invalid input file, 3 for an internal consistency
+error (e.g., bug) which caused ed to panic.
.SH "REPORTING BUGS"
Report bugs to bug\-ed@gnu.org
.br
@@ -61,7 +64,7 @@ General help using GNU software: http://www.gnu.org/gethelp
.SH COPYRIGHT
Copyright \(co 1994 Andrew L. Moore.
.br
-Copyright \(co 2022 Antonio Diaz Diaz.
+Copyright \(co 2023 Antonio Diaz Diaz.
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
.br
This is free software: you are free to change and redistribute it.
diff --git a/doc/ed.info b/doc/ed.info
index b4510a1..9997b7b 100644
--- a/doc/ed.info
+++ b/doc/ed.info
@@ -5,7 +5,7 @@ START-INFO-DIR-ENTRY
* Ed: (ed). The GNU line editor
END-INFO-DIR-ENTRY
- Copyright (C) 1993, 1994, 2006-2022 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 2006-2023 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or any
@@ -18,7 +18,7 @@ File: ed.info, Node: Top, Next: Overview, Up: (dir)
The GNU ed line editor
**********************
-This manual is for GNU ed (version 1.18, 4 February 2022).
+This manual is for GNU ed (version 1.19, 11 January 2023).
* Menu:
@@ -35,7 +35,7 @@ This manual is for GNU ed (version 1.18, 4 February 2022).
* GNU Free Documentation License:: How you can copy and share this manual
- Copyright (C) 1993, 1994, 2006-2022 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 2006-2023 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or any
@@ -288,8 +288,8 @@ is an exception, and may be appended to the end of most commands.
address of the last line of that file. Similarly, the move command 'm' sets
the current address to the address of the last line moved.
- Related programs or routines are 'vi (1)', 'sed (1)', 'regex (3)', 'sh
-(1)'. Relevant documents are:
+ Related programs or routines are 'vi'(1), 'sed'(1), 'regex'(3), 'sh'(1).
+Relevant documents are:
Unix User's Manual Supplementary Documents: 12 -- 13
@@ -309,8 +309,8 @@ The format for running 'ed' is:
FILE specifies the name of a file to read. If FILE is prefixed with a
bang (!), then it is interpreted as a shell command. In this case, what is
-read is the standard output of FILE executed via 'sh (1)'. To read a file
-whose name begins with a bang, prefix the name with a backslash ('\'). The
+read is the standard output of FILE executed via 'sh'. To read a file whose
+name begins with a bang (or a hyphen), prefix the name with './'. The
default filename is set to FILE only if it is not prefixed with a bang.
'ed' supports the following options: *Note Argument syntax:
@@ -333,7 +333,7 @@ default filename is set to FILE only if it is not prefixed with a bang.
'-G'
'--traditional'
Forces backwards compatibility. This affects the behavior of the 'ed'
- commands 'G', 'V', 'f', 'l', 'm', 't' and '!!'. If the default
+ commands 'G', 'V', 'f', 'l', 'm', 't', and '!!'. If the default
behavior of these commands does not seem familiar, then try invoking
'ed' with this switch.
@@ -348,22 +348,28 @@ default filename is set to FILE only if it is not prefixed with a bang.
Specifies a command prompt string and turns prompting on. Showing the
prompt string may be toggled on and off with the 'P' command.
+'-q'
+'--quiet'
+'--silent'
+ Suppress diagnostic messages written to standard error.
+
'-r'
'--restricted'
Run in restricted mode. This mode disables editing of files out of the
current directory and execution of shell commands.
'-s'
-'--quiet'
-'--silent'
- Suppresses diagnostics, the printing of byte counts by 'e', 'E', 'r'
- and 'w' commands, and the '!' prompt after a '!' command. This option
- may be useful if 'ed''s standard input is from a script.
+'--script'
+ Suppress the printing of byte counts by 'e', 'E', 'r', and 'w'
+ commands, and the '!' prompt after a '!' command. This option does not
+ suppress diagnostic messages written to standard error (see '-q'
+ above). '-s' may be useful if 'ed''s standard input is from a script.
'-v'
'--verbose'
- Verbose mode; prints error explanations. This may be toggled on and off
- with the 'H' command.
+ Turn help mode on; print a help message explaining the reason for each
+ '?' notification. This may be toggled on and off with the 'H' command.
+ Use this option to aid in debugging ed scripts.
'--strip-trailing-cr'
Strip the carriage returns at the end of text lines in DOS files. CRs
@@ -393,11 +399,14 @@ address '0' (zero). This means "at the beginning of the buffer", and is
valid wherever it makes sense.
An address range is two addresses separated either by a comma (',') or a
-semicolon (';'). In a semicolon-delimited range, the current address ('.')
-is set to the first address before the second address is calculated. This
-feature can be used to set the starting line for searches if the second
-address contains a regular expression. The value of the first address in a
-range cannot exceed the value of the second.
+semicolon (';'). The value of the first address in a range cannot exceed
+the value of the second.
+
+ In a semicolon-delimited range, the current address ('.') is set to the
+first address before the second address is calculated. This feature can be
+used to set the starting line for searches if the second address contains a
+regular expression. The address '0' (zero) is valid as a starting point so
+that '0;/RE/' can match RE in the first line of the buffer.
Addresses can be omitted on either side of the comma or semicolon
separator. If only the first address is given in a range, then the second
@@ -454,8 +463,8 @@ of addresses to a command that requires zero addresses.
in a case-insensitive manner.
''x'
- The apostrophe-x character pair addresses the line previously marked by
- a 'k' (mark) command, where 'x' is a lower case letter from the
+ The apostrophe-x character pair addresses the line previously marked
+ by a 'k' (mark) command, where 'x' is a lower case letter from the
portable character set '[a-z]'.
@@ -511,12 +520,12 @@ it is invalid to specify it together with the empty regular expression.
POSIX basic regular expression syntax:
'C'
- Any character C not listed below, including '{', '}', '(', ')', '<'
+ Any character C not listed below, including '{', '}', '(', ')', '<',
and '>', matches itself.
'\C'
Any backslash-escaped character C, other than '{', '}', '(', ')', '<',
- '>', 'b', 'B', 'w', 'W', '+' and '?', matches itself.
+ '>', 'b', 'B', 'w', 'W', '+', and '?', matches itself.
'.'
Matches any single character.
@@ -541,7 +550,7 @@ POSIX basic regular expression syntax:
[=COL-ELM=]
where COL-ELM is a "collating element" are interpreted according to
- 'locale (5)'. See 'regex (7)' for an explanation of these constructs.
+ 'locale'(5). See 'regex'(7) for an explanation of these constructs.
'[^CHAR-CLASS]'
Matches any single character, other than newline, not in CHAR-CLASS.
@@ -692,7 +701,8 @@ parenthesis).
If FILE is prefixed with a bang (!), then it is interpreted as a shell
command whose output is to be read, (*note shell escape command:: '!'
- below). In this case the default filename is unchanged.
+ below). In this case the default filename is unchanged. To edit a file
+ whose name begins with a bang, prefix the name with './'.
A warning is printed if any changes have been made in the buffer since
the last 'w' command that wrote the entire buffer to a file.
@@ -703,7 +713,7 @@ parenthesis).
'f FILE'
Sets the default filename to FILE. If FILE is not specified, then the
- default unescaped filename is printed.
+ default filename is printed.
'(1,$)g/RE/[I]COMMAND-LIST'
Global command. The global command makes two passes over the file. On
@@ -743,12 +753,14 @@ parenthesis).
last non-empty command list.
'h'
- Help. Prints an explanation of the last error.
+ Prints a help message explaining the reason for the most recent '?'
+ notification.
'H'
- Toggles the printing of error explanations. By default, explanations
- are not printed. It is recommended that ed scripts begin with this
- command to aid in debugging.
+ Toggles the printing of help messages (see the 'h' command above). If
+ the help mode is being turned on, also prints the help message
+ corresponding to the most recent '?' notification. By default, help
+ messages are not printed.
'(.)i'
Inserts text in the buffer before the addressed line. The address '0'
@@ -819,7 +831,8 @@ parenthesis).
If FILE is prefixed with a bang (!), then it is interpreted as a shell
command whose output is to be read, (*note shell escape command:: '!'
- below). In this case the default filename is unchanged.
+ below). In this case the default filename is unchanged. To read a file
+ whose name begins with a bang, prefix the name with './'.
'(.,.)t(.)'
Copies (i.e., transfers) the addressed lines to after the right-hand
@@ -854,7 +867,8 @@ parenthesis).
(*note shell escape command:: '!' below). In this case the default
filename is unchanged. Writing the buffer to a shell command does not
prevent the warning to the user if an attempt is made to overwrite or
- discard the buffer via the 'e' or 'q' commands.
+ discard the buffer via the 'e' or 'q' commands. To write to a file
+ whose name begins with a bang, prefix the name with './'.
'(1,$)wq FILE'
Writes the addressed lines to FILE, and then executes a 'q' command.
@@ -882,7 +896,7 @@ parenthesis).
address of the last line printed.
'!COMMAND'
- Shell escape command. Executes COMMAND via 'sh (1)'. If the first
+ Shell escape command. Executes COMMAND via 'sh'. If the first
character of COMMAND is '!', then it is replaced by the text of the
previous '!COMMAND'. Thus, '!!' repeats the previous '!COMMAND'. 'ed'
does not process COMMAND for backslash ('\') escapes. However, each
@@ -891,6 +905,13 @@ parenthesis).
execution, a '!' is printed to the standard output. The current
address is unchanged.
+ The effect of ex(1) style '!' filtering can be achieved with the
+ following sequence of commands:
+ ADDR1,ADDR2w !COMMAND > tmp.txt 2>&1
+ ADDR2r tmp.txt
+ ADDR1,ADDR2d
+ !rm tmp.txt
+
'(.,.)#'
Begins a comment; the rest of the line, up to a newline, is ignored.
If a line address followed by a semicolon is given, then the current
@@ -948,7 +969,7 @@ current address is unchanged. The last line modified is copied to the cut
buffer.
RE and REPLACEMENT may be delimited by any character other than <space>,
-<newline> and the characters used by the form of the 's' command shown
+<newline>, and the characters used by the form of the 's' command shown
below. If the last delimiter is omitted, then the last line affected is
printed as if the print suffix 'p' were specified. The last delimiter can't
be omitted if the 's' command is part of a 'g' or 'v' COMMAND-LIST and is
@@ -988,16 +1009,11 @@ File: ed.info, Node: Limitations, Next: Diagnostics, Prev: The 's' Command,
If the terminal hangs up, 'ed' attempts to write the buffer to the file
'ed.hup' or, if this fails, to '$HOME/ed.hup'.
- 'ed' processes FILE arguments for backslash escapes, i.e., in a
-filename, any character preceded by a backslash ('\') is interpreted
-literally. For example, 'ed 'hello\tworld'' will edit the file
-'hellotworld'.
-
If a text (non-binary) file is not terminated by a newline character,
then 'ed' appends one on reading/writing it. In the case of a binary file,
'ed' does not append a newline on reading/writing. A binary file is one
containing at least one ASCII NUL character. If the last line has been
-modified, reading an empty file, for example /dev/null, prior to writing
+modified, reading an empty file, for example '/dev/null', prior to writing
prevents appending a newline to a binary file.
In order to keep track of the text lines in the buffer, 'ed' uses a
@@ -1012,7 +1028,12 @@ File: ed.info, Node: Diagnostics, Next: Problems, Prev: Limitations, Up: Top
9 Diagnostics
*************
-When an error occurs, if 'ed''s input is from a regular file or here
+'ed' prints two kinds of error mesages: diagnostic messages written to
+standard error and help messages written to standard output. Diagnostic
+messages may be suppresed with option '-q'. Help messages may be enabled
+with option '-v' and may be toggled with command 'H'.
+
+ When an error occurs, if 'ed''s input is from a regular file or here
document, then it exits, otherwise it prints a '?' and returns to command
mode. An explanation of the last error can be printed with the 'h' (help)
command.
@@ -1508,17 +1529,17 @@ Tag Table:
Node: Top535
Node: Overview1764
Node: Introduction to line editing4317
-Node: Invoking ed11588
-Node: Line addressing14245
-Node: Regular expressions18159
-Node: Commands24344
-Ref: print suffixes24679
-Ref: shell escape command36257
-Node: The 's' Command37340
-Node: Limitations40254
-Node: Diagnostics41449
-Node: Problems42094
-Node: GNU Free Documentation License42629
+Node: Invoking ed11584
+Node: Line addressing14496
+Node: Regular expressions18529
+Node: Commands24714
+Ref: print suffixes25049
+Ref: shell escape command36962
+Node: The 's' Command38266
+Node: Limitations41181
+Node: Diagnostics42163
+Node: Problems43082
+Node: GNU Free Documentation License43617

End Tag Table
diff --git a/doc/ed.texi b/doc/ed.texi
index 2ad831a..614e1b3 100644
--- a/doc/ed.texi
+++ b/doc/ed.texi
@@ -6,8 +6,8 @@
@finalout
@c %**end of header
-@set UPDATED 4 February 2022
-@set VERSION 1.18
+@set UPDATED 11 January 2023
+@set VERSION 1.19
@dircategory Basics
@direntry
@@ -15,7 +15,7 @@
@end direntry
@copying
-Copyright @copyright{} 1993, 1994, 2006-2022 Free Software Foundation, Inc.
+Copyright @copyright{} 1993, 1994, 2006-2023 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -170,12 +170,11 @@ P
*
@end example
-By default, @command{ed} uses asterisk (@samp{*}) as command prompt to
-avoid confusion with the shell command prompt (@samp{$}).
+By default, @command{ed} uses asterisk (@samp{*}) as command prompt to avoid
+confusion with the shell command prompt (@samp{$}).
-We can run Unix shell (@command{sh}) commands from inside @command{ed}
-by prefixing them with @key{!} (exclamation mark, aka "bang"). For
-example:
+We can run Unix shell (@command{sh}) commands from inside @command{ed} by
+prefixing them with @key{!} (exclamation mark, aka "bang"). For example:
@example
*!date
@@ -338,8 +337,8 @@ When @command{ed} opens a file, the current address is initially set to
the address of the last line of that file. Similarly, the move command
@samp{m} sets the current address to the address of the last line moved.
-Related programs or routines are @command{vi (1)}, @command{sed (1)},
-@command{regex (3)}, @command{sh (1)}. Relevant documents are:
+Related programs or routines are @command{vi}(1), @command{sed}(1),
+@command{regex}(3), @command{sh}(1). Relevant documents are:
@quotation
Unix User's Manual Supplementary Documents: 12 --- 13
@@ -361,12 +360,12 @@ ed [@var{options}] [@var{file}]
red [@var{options}] [@var{file}]
@end example
-@var{file} specifies the name of a file to read. If @var{file} is
-prefixed with a bang (!), then it is interpreted as a shell command. In
-this case, what is read is the standard output of @var{file} executed
-via @command{sh (1)}. To read a file whose name begins with a bang,
-prefix the name with a backslash (@kbd{\}). The default filename is set
-to @var{file} only if it is not prefixed with a bang.
+@var{file} specifies the name of a file to read. If @var{file} is prefixed
+with a bang (!), then it is interpreted as a shell command. In this case,
+what is read is the standard output of @var{file} executed via @command{sh}.
+To read a file whose name begins with a bang (or a hyphen), prefix the name
+with @file{./}. The default filename is set to @var{file} only if it is not
+prefixed with a bang.
@command{ed} supports the following
@uref{http://www.nongnu.org/arg-parser/manual/arg_parser_manual.html#Argument-syntax,,options}:
@@ -393,7 +392,7 @@ mandated by POSIX.
@itemx --traditional
Forces backwards compatibility. This affects the behavior of the
@command{ed} commands @samp{G}, @samp{V}, @samp{f}, @samp{l}, @samp{m},
-@samp{t} and @samp{!!}. If the default behavior of these commands does
+@samp{t}, and @samp{!!}. If the default behavior of these commands does
not seem familiar, then try invoking @command{ed} with this switch.
@item -l
@@ -407,23 +406,29 @@ when @command{ed} is invoked as the editor for crontab.
Specifies a command prompt string and turns prompting on. Showing the prompt
string may be toggled on and off with the @samp{P} command.
+@item -q
+@itemx --quiet
+@itemx --silent
+Suppress diagnostic messages written to standard error.
+
@item -r
@itemx --restricted
Run in restricted mode. This mode disables editing of files out of the
current directory and execution of shell commands.
@item -s
-@itemx --quiet
-@itemx --silent
-Suppresses diagnostics, the printing of byte counts by @samp{e},
-@samp{E}, @samp{r} and @samp{w} commands, and the @samp{!} prompt after
-a @samp{!} command. This option may be useful if @command{ed}'s standard
+@itemx --script
+Suppress the printing of byte counts by @samp{e}, @samp{E}, @samp{r}, and
+@samp{w} commands, and the @samp{!} prompt after a @samp{!} command. This
+option does not suppress diagnostic messages written to standard error (see
+@option{-q} above). @option{-s} may be useful if @command{ed}'s standard
input is from a script.
@item -v
@itemx --verbose
-Verbose mode; prints error explanations. This may be toggled on and off
-with the @samp{H} command.
+Turn help mode on; print a help message explaining the reason for each
+@samp{?} notification. This may be toggled on and off with the @samp{H}
+command. Use this option to aid in debugging ed scripts.
@item --strip-trailing-cr
Strip the carriage returns at the end of text lines in DOS files. CRs are
@@ -441,32 +446,35 @@ Exit status: 0 if no errors occurred; otherwise >0.
@chapter Line addressing
An address represents the number of a line in the buffer. @command{ed}
-maintains a @dfn{current address} which is typically supplied to
-commands as the default address when none is specified. When a file is
-first read, the current address is set to the address of the last line
-of the file. In general, the current address is set to the address of
-the last line affected by a command.
+maintains a @dfn{current address} which is typically supplied to commands as
+the default address when none is specified. When a file is first read, the
+current address is set to the address of the last line of the file. In
+general, the current address is set to the address of the last line affected
+by a command.
One exception to the rule that addresses represent line numbers is the
-address @samp{0} (zero). This means "at the beginning of the buffer",
-and is valid wherever it makes sense.
+address @samp{0} (zero). This means "at the beginning of the buffer", and is
+valid wherever it makes sense.
An address range is two addresses separated either by a comma (@samp{,}) or
-a semicolon (@samp{;}). In a semicolon-delimited range, the current address
-(@samp{.}) is set to the first address before the second address is
-calculated. This feature can be used to set the starting line for searches
-if the second address contains a regular expression. The value of the first
-address in a range cannot exceed the value of the second.
-
-Addresses can be omitted on either side of the comma or semicolon
-separator. If only the first address is given in a range, then the
-second address is set to the given address. If only the second address
-is given, the resulting address pairs are @samp{1,addr} and
-@samp{.;addr} respectively. If a @var{n}-tuple of addresses is given
-where @var{n} > 2, then the corresponding range is determined by the
-last two addresses in the @var{n}-tuple. If only one address is
-expected, then the last address is used. It is an error to give any
-number of addresses to a command that requires zero addresses.
+a semicolon (@samp{;}). The value of the first address in a range cannot
+exceed the value of the second.
+
+In a semicolon-delimited range, the current address (@samp{.}) is set to the
+first address before the second address is calculated. This feature can be
+used to set the starting line for searches if the second address contains a
+regular expression. The address @samp{0} (zero) is valid as a starting point
+so that @samp{0;/@var{re}/} can match @var{re} in the first line of the buffer.
+
+Addresses can be omitted on either side of the comma or semicolon separator.
+If only the first address is given in a range, then the second address is
+set to the given address. If only the second address is given, the resulting
+address pairs are @samp{1,addr} and @samp{.;addr} respectively. If a
+@var{n}-tuple of addresses is given where @w{@var{n} > 2}, then the
+corresponding range is determined by the last two addresses in the
+@var{n}-tuple. If only one address is expected, then the last address is
+used. It is an error to give any number of addresses to a command that
+requires zero addresses.
A line address is constructed as follows:
@@ -492,8 +500,8 @@ The next line. This is equivalent to @samp{+1} and may be repeated with
cumulative effect.
@item -
-The previous line. This is equivalent to @samp{-1} and may be repeated
-with cumulative effect.
+The previous line. This is equivalent to @samp{-1} and may be repeated with
+cumulative effect.
@item ,
The first through last lines in the buffer. This is equivalent to the
@@ -504,10 +512,10 @@ The current through last lines in the buffer. This is equivalent to the
address range @samp{.;$}.
@item /@var{re}/[I]
-The next line containing the regular expression @var{re}. The search
-wraps to the beginning of the buffer and continues down to the current
-line, if necessary. The suffix @samp{I} is a GNU extension which makes
-@command{ed} match @var{re} in a case-insensitive manner.
+The next line containing the regular expression @var{re}. The search wraps
+to the beginning of the buffer and continues down to the current line, if
+necessary. The suffix @samp{I} is a GNU extension which makes @command{ed}
+match @var{re} in a case-insensitive manner.
@item ?@var{re}?[I]
The previous line containing the regular expression @var{re}. The search
@@ -516,9 +524,9 @@ necessary. The suffix @samp{I} is a GNU extension which makes @command{ed}
match @var{re} in a case-insensitive manner.
@item 'x
-The apostrophe-x character pair addresses the line previously marked by
-a @samp{k} (mark) command, where @samp{x} is a lower case letter from
-the portable character set @samp{[a-z]}.
+The apostrophe-x character pair addresses the line previously marked by a
+@samp{k} (mark) command, where @samp{x} is a lower case letter from the
+portable character set @samp{[a-z]}.
@end table
@@ -531,8 +539,8 @@ separated by whitespace. Offsets are constructed as follows:
number of lines to or from the address.
@item
-@samp{+} or @samp{-} not followed by a number adds or subtracts 1 to or
-from the address.
+@samp{+} or @samp{-} not followed by a number adds or subtracts 1 to or from
+the address.
@item
A number adds the indicated number of lines to the address.
@@ -584,12 +592,12 @@ POSIX basic regular expression syntax:
@item @var{c}
Any character @var{c} not listed below, including @samp{@{}, @samp{@}},
-@samp{(}, @samp{)}, @samp{<} and @samp{>}, matches itself.
+@samp{(}, @samp{)}, @samp{<}, and @samp{>}, matches itself.
@item \@var{c}
Any backslash-escaped character @var{c}, other than @samp{@{},
@samp{@}}, @samp{(}, @samp{)}, @samp{<}, @samp{>}, @samp{b}, @samp{B},
-@samp{w}, @samp{W}, @samp{+} and @samp{?}, matches itself.
+@samp{w}, @samp{W}, @samp{+}, and @samp{?}, matches itself.
@item .
Matches any single character.
@@ -620,7 +628,7 @@ Patterns in @var{char-class} of the form:
@noindent
where @var{col-elm} is a @dfn{collating element} are interpreted according
-to @samp{locale (5)}. See @samp{regex (7)} for an explanation of these
+to @samp{locale}(5). See @samp{regex}(7) for an explanation of these
constructs.
@item [^@var{char-class}]
@@ -773,24 +781,25 @@ buffer.
@item e @var{file}
Edits @var{file}, and sets the default filename. If @var{file} is not
-specified, then the default filename is used. Any lines in the buffer
-are deleted before the new file is read. The current address is set to
-the address of the last line in the buffer.
+specified, then the default filename is used. Any lines in the buffer are
+deleted before the new file is read. The current address is set to the
+address of the last line in the buffer.
-If @var{file} is prefixed with a bang (!), then it is interpreted as a
-shell command whose output is to be read, (@pxref{shell escape command}
-@samp{!} below). In this case the default filename is unchanged.
+If @var{file} is prefixed with a bang (!), then it is interpreted as a shell
+command whose output is to be read, (@pxref{shell escape command} @samp{!}
+below). In this case the default filename is unchanged. To edit a file whose
+name begins with a bang, prefix the name with @file{./}.
-A warning is printed if any changes have been made in the buffer since
-the last @samp{w} command that wrote the entire buffer to a file.
+A warning is printed if any changes have been made in the buffer since the
+last @samp{w} command that wrote the entire buffer to a file.
@item E @var{file}
-Edits @var{file} unconditionally. This is similar to the @samp{e}
-command, except that unwritten changes are discarded without warning.
+Edits @var{file} unconditionally. This is similar to the @samp{e} command,
+except that unwritten changes are discarded without warning.
@item f @var{file}
Sets the default filename to @var{file}. If @var{file} is not specified,
-then the default unescaped filename is printed.
+then the default filename is printed.
@item (1,$)g/@var{re}/[I]@var{command-list}
Global command. The global command makes two passes over the file. On the
@@ -813,7 +822,7 @@ allowed, except for @samp{g}, @samp{G}, @samp{v}, and @samp{V}. The @samp{.}
terminating the input mode of commands @samp{a}, @samp{c}, and @samp{i} can
be omitted if it would be the last line of @var{command-list}. By default, a
newline alone in @var{command-list} is equivalent to a @samp{p} command. If
-@command{ed} is invoked with the command-line option @samp{-G}, then a
+@command{ed} is invoked with the command-line option @option{-G}, then a
newline in @var{command-list} is equivalent to a @samp{.+1p} command.
@item (1,$)G/@var{re}/[I]
@@ -830,12 +839,14 @@ command. A newline alone acts as an empty command list. A single @samp{&}
repeats the last non-empty command list.
@item h
-Help. Prints an explanation of the last error.
+Prints a help message explaining the reason for the most recent @samp{?}
+notification.
@item H
-Toggles the printing of error explanations. By default, explanations are
-not printed. It is recommended that ed scripts begin with this command
-to aid in debugging.
+Toggles the printing of help messages (see the @samp{h} command above). If
+the help mode is being turned on, also prints the help message corresponding
+to the most recent @samp{?} notification. By default, help messages are not
+printed.
@item (.)i
Inserts text in the buffer before the addressed line. The address
@@ -883,7 +894,7 @@ the last line printed.
@item P
Toggles the command prompt on and off. Unless a prompt string is specified
-with the command-line option @samp{-p}, the command prompt is by default
+with the command-line option @option{-p}, the command prompt is by default
turned off. The default prompt string is an asterisk (@samp{*}).
@item q
@@ -904,9 +915,10 @@ to @var{file}. Otherwise, the default filename is unchanged. The address
beginning of the buffer. The current address is set to the address of
the last line read or, if there were none, to the addressed line.
-If @var{file} is prefixed with a bang (!), then it is interpreted as a
-shell command whose output is to be read, (@pxref{shell escape command}
-@samp{!} below). In this case the default filename is unchanged.
+If @var{file} is prefixed with a bang (!), then it is interpreted as a shell
+command whose output is to be read, (@pxref{shell escape command} @samp{!}
+below). In this case the default filename is unchanged. To read a file whose
+name begins with a bang, prefix the name with @file{./}.
@item (.,.)t(.)
Copies (i.e., transfers) the addressed lines to after the right-hand
@@ -942,7 +954,8 @@ shell command and the addressed lines are written to its standard input,
(@pxref{shell escape command} @samp{!} below). In this case the default
filename is unchanged. Writing the buffer to a shell command does not
prevent the warning to the user if an attempt is made to overwrite or
-discard the buffer via the @samp{e} or @samp{q} commands.
+discard the buffer via the @samp{e} or @samp{q} commands. To write to a file
+whose name begins with a bang, prefix the name with @file{./}.
@item (1,$)wq @var{file}
Writes the addressed lines to @var{file}, and then executes a @samp{q}
@@ -971,14 +984,23 @@ address of the last line printed.
@anchor{shell escape command}
@item !@var{command}
-Shell escape command. Executes @var{command} via @command{sh (1)}. If the
-first character of @var{command} is @samp{!}, then it is replaced by the
-text of the previous @samp{!@var{command}}. Thus, @samp{!!} repeats the
-previous @samp{!@var{command}}. @command{ed} does not process @var{command}
-for backslash (@samp{\}) escapes. However, each unescaped @samp{%} is
-replaced with the default filename, and the backslash is removed from each
-escaped @samp{%}. When the shell returns from execution, a @samp{!} is
-printed to the standard output. The current address is unchanged.
+Shell escape command. Executes @var{command} via @command{sh}. If the first
+character of @var{command} is @samp{!}, then it is replaced by the text of
+the previous @samp{!@var{command}}. Thus, @samp{!!} repeats the previous
+@samp{!@var{command}}. @command{ed} does not process @var{command} for
+backslash (@samp{\}) escapes. However, each unescaped @samp{%} is replaced
+with the default filename, and the backslash is removed from each escaped
+@samp{%}. When the shell returns from execution, a @samp{!} is printed to
+the standard output. The current address is unchanged.
+
+The effect of ex(1) style @samp{!} filtering can be achieved with the
+following sequence of commands:
+@example
+@var{addr1},@var{addr2}w !@var{command} > tmp.txt 2>&1
+@var{addr2}r tmp.txt
+@var{addr1},@var{addr2}d
+!rm tmp.txt
+@end example
@item (.,.)#
Begins a comment; the rest of the line, up to a newline, is ignored. If a
@@ -1041,7 +1063,7 @@ current address is unchanged. The last line modified is copied to the cut
buffer.
@var{re} and @var{replacement} may be delimited by any character other
-than @key{space}, @key{newline} and the characters used by the form of
+than @key{space}, @key{newline}, and the characters used by the form of
the @samp{s} command shown below. If the last delimiter is omitted, then
the last line affected is printed as if the print suffix @samp{p} were
specified. The last delimiter can't be omitted if the @samp{s} command
@@ -1080,20 +1102,15 @@ substitution (if the search happened after the substitution).
@node Limitations
@chapter Limitations
-If the terminal hangs up, @command{ed} attempts to write the buffer to
-the file @file{ed.hup} or, if this fails, to @file{$HOME/ed.hup}.
-
-@command{ed} processes @var{file} arguments for backslash escapes, i.e., in
-a filename, any character preceded by a backslash (@samp{\}) is interpreted
-literally. For example, @w{@samp{ed 'hello\tworld'}} will edit the file
-@samp{hellotworld}.
+If the terminal hangs up, @command{ed} attempts to write the buffer to the
+file @file{ed.hup} or, if this fails, to @file{$HOME/ed.hup}.
If a text (non-binary) file is not terminated by a newline character, then
@command{ed} appends one on reading/writing it. In the case of a binary
file, @command{ed} does not append a newline on reading/writing. A binary
file is one containing at least one ASCII NUL character. If the last line
-has been modified, reading an empty file, for example /dev/null, prior to
-writing prevents appending a newline to a binary file.
+has been modified, reading an empty file, for example @file{/dev/null},
+prior to writing prevents appending a newline to a binary file.
In order to keep track of the text lines in the buffer, @command{ed} uses a
doubly linked list of structures containing the position and size of each
@@ -1105,6 +1122,11 @@ line. This results in a per line overhead of @w{2 @samp{pointer}s},
@node Diagnostics
@chapter Diagnostics
+@command{ed} prints two kinds of error mesages: diagnostic messages written
+to standard error and help messages written to standard output. Diagnostic
+messages may be suppresed with option @option{-q}. Help messages may be
+enabled with option @option{-v} and may be toggled with command @samp{H}.
+
When an error occurs, if @command{ed}'s input is from a regular file or
here document, then it exits, otherwise it prints a @samp{?} and returns
to command mode. An explanation of the last error can be printed with
diff --git a/ed.h b/ed.h
index db0b4a6..cbd6dfd 100644
--- a/ed.h
+++ b/ed.h
@@ -1,7 +1,7 @@
/* Global declarations for the ed editor. */
/* GNU ed - The GNU line editor.
- Copyright (C) 1993, 1994 Andrew Moore, Talke Studio
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 1993, 1994 Andrew L. Moore, Talke Studio
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -111,7 +111,7 @@ void unmark_unterminated_line( const line_t * const lp );
/* defined in main.c */
bool extended_regexp( void );
-bool is_regular_file( const int fd );
+bool interactive();
bool may_access_filename( const char * const name );
bool restricted( void );
bool scripted( void );
@@ -146,6 +146,5 @@ void enable_interrupts( void );
bool resize_buffer( char ** const buf, int * const size, const unsigned min_size );
void set_signals( void );
void set_window_lines( const int lines );
-const char * strip_escapes( const char * p );
int window_columns( void );
int window_lines( void );
diff --git a/global.c b/global.c
index 4572e18..0605ea5 100644
--- a/global.c
+++ b/global.c
@@ -1,7 +1,7 @@
/* global.c: global command routines for the ed line editor */
/* GNU ed - The GNU line editor.
- Copyright (C) 1993, 1994 Andrew Moore, Talke Studio
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 1993, 1994 Andrew L. Moore, Talke Studio
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ bool set_active_node( const line_t * const lp )
if( min_size >= INT_MAX )
{ set_error_msg( "Too many matching lines" ); return false; }
const int new_size = ( ( min_size < 512 ) ? 512 :
- ( min_size > INT_MAX / 2 ) ? INT_MAX : ( min_size / 512 ) * 1024 );
+ ( min_size >= INT_MAX / 2 ) ? INT_MAX - 1 : ( min_size / 512 ) * 1024 );
void * new_buf = 0;
disable_interrupts();
if( active_list ) new_buf = realloc( active_list, new_size );
diff --git a/io.c b/io.c
index 2f9bd59..9e4b950 100644
--- a/io.c
+++ b/io.c
@@ -1,7 +1,7 @@
/* io.c: i/o routines for the ed line editor */
/* GNU ed - The GNU line editor.
- Copyright (C) 1993, 1994 Andrew Moore, Talke Studio
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 1993, 1994 Andrew L. Moore, Talke Studio
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -108,7 +108,8 @@ static bool trailing_escape( const char * const s, int len )
/* If *ibufpp contains an escaped newline, get an extended line (one
with escaped newlines) from stdin.
The backslashes escaping the newlines are stripped.
- Return line length in *lenp, including the trailing newline. */
+ Return line length in *lenp, including the trailing newline.
+*/
bool get_extended_line( const char ** const ibufpp, int * const lenp,
const bool strip_escaped_newlines )
{
@@ -177,7 +178,7 @@ const char * get_stdin_line( int * const sizep )
}
else
{
- buf[i++] = c; if( !c ) set_binary(); if( c != '\n' ) continue;
+ buf[i++] = c; if( c == 0 ) set_binary(); if( c != '\n' ) continue;
++linenum_; buf[i] = 0; *sizep = i;
return buf;
}
@@ -202,7 +203,7 @@ static const char * read_stream_line( const char * const filename,
if( !resize_buffer( &buf, &bufsz, i + 2 ) ) return 0;
c = getc( fp ); if( c == EOF ) break;
buf[i++] = c;
- if( !c ) set_binary();
+ if( c == 0 ) set_binary();
else if( c == '\n' ) /* remove CR only from CR/LF pairs */
{ if( strip_cr() && i > 1 && buf[i-2] == '\r' ) { buf[i-2] = '\n'; --i; }
break; }
@@ -227,14 +228,15 @@ static const char * read_stream_line( const char * const filename,
}
-/* read a stream into the editor buffer;
- return total size of data read, or -1 if error */
+/* Read a stream into the editor buffer.
+ Return number of bytes read, or -1 if error.
+*/
static long read_stream( const char * const filename, FILE * const fp,
const int addr )
{
line_t * lp = search_line_node( addr );
undo_t * up = 0;
- long total_size = 0;
+ long total_size = 0; /* number of bytes read */
const bool o_isbinary = isbinary();
const bool appended = ( addr == last_addr() );
const bool o_unterminated_last_line = unterminated_last_line();
@@ -279,16 +281,11 @@ static long read_stream( const char * const filename, FILE * const fp,
int read_file( const char * const filename, const int addr )
{
FILE * fp;
- long size;
+ long size; /* number of bytes read */
int ret;
if( *filename == '!' ) fp = popen( filename + 1, "r" );
- else
- {
- const char * const stripped_name = strip_escapes( filename );
- if( !stripped_name ) return -2;
- fp = fopen( stripped_name, "r" );
- }
+ else fp = fopen( filename, "r" );
if( !fp )
{
show_strerror( filename, errno );
@@ -309,12 +306,14 @@ int read_file( const char * const filename, const int addr )
}
-/* write a range of lines to a stream */
+/* Write a range of lines to a stream.
+ Return number of bytes written, or -1 if error.
+*/
static long write_stream( const char * const filename, FILE * const fp,
int from, const int to )
{
line_t * lp = search_line_node( from );
- long size = 0;
+ long size = 0; /* number of bytes written */
while( from && from <= to )
{
@@ -338,21 +337,18 @@ static long write_stream( const char * const filename, FILE * const fp,
}
-/* write a range of lines to a named file/pipe; return line count */
+/* Write a range of lines to a named file/pipe.
+ Return line count, or -1 if error.
+*/
int write_file( const char * const filename, const char * const mode,
const int from, const int to )
{
FILE * fp;
- long size;
+ long size; /* number of bytes written */
int ret;
if( *filename == '!' ) fp = popen( filename + 1, "w" );
- else
- {
- const char * const stripped_name = strip_escapes( filename );
- if( !stripped_name ) return -1;
- fp = fopen( stripped_name, mode );
- }
+ else fp = fopen( filename, mode );
if( !fp )
{
show_strerror( filename, errno );
diff --git a/main.c b/main.c
index 1e38ca0..d980cdd 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
/* GNU ed - The GNU line editor.
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,9 +16,9 @@
*/
/*
Exit status: 0 for a normal exit, 1 for environmental problems
- (file not found, invalid flags, I/O errors, etc), 2 to indicate a
- corrupt or invalid input file, 3 for an internal consistency error
- (e.g., bug) which caused ed to panic.
+ (file not found, invalid command line options, I/O errors, etc), 2 to
+ indicate a corrupt or invalid input file, 3 for an internal consistency
+ error (e.g., bug) which caused ed to panic.
*/
/*
* CREDITS
@@ -43,13 +43,14 @@
static const char * const program_name = "ed";
-static const char * const program_year = "2022";
+static const char * const program_year = "2023";
static const char * invocation_name = "ed"; /* default value */
static bool extended_regexp_ = false; /* if set, use EREs */
+static bool quiet_ = false; /* if set, suppress diagnostics */
static bool restricted_ = false; /* if set, run in restricted mode */
-static bool scripted_ = false; /* if set, suppress diagnostics,
- byte counts and '!' prompt */
+static bool scripted_ = false; /* if set, suppress byte counts and
+ '!' prompt */
static bool strip_cr_ = false; /* if set, strip trailing CRs */
static bool traditional_ = false; /* if set, be backwards compatible */
@@ -78,16 +79,17 @@ static void show_help( void )
" -G, --traditional run in compatibility mode\n"
" -l, --loose-exit-status exit with 0 status even if a command fails\n"
" -p, --prompt=STRING use STRING as an interactive prompt\n"
+ " -q, --quiet, --silent suppress diagnostics written to stderr\n"
" -r, --restricted run in restricted mode\n"
- " -s, --quiet, --silent suppress diagnostics, byte counts and '!' prompt\n"
+ " -s, --script suppress byte counts and '!' prompt\n"
" -v, --verbose be verbose; equivalent to the 'H' command\n"
" --strip-trailing-cr strip carriage returns at end of text lines\n"
"\nStart edit by reading in 'file' if given.\n"
"If 'file' begins with a '!', read output of shell command.\n"
- "\nExit status: 0 for a normal exit, 1 for environmental problems (file\n"
- "not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or\n"
- "invalid input file, 3 for an internal consistency error (e.g., bug) which\n"
- "caused ed to panic.\n"
+ "\nExit status: 0 for a normal exit, 1 for environmental problems\n"
+ "(file not found, invalid command line options, I/O errors, etc), 2 to\n"
+ "indicate a corrupt or invalid input file, 3 for an internal consistency\n"
+ "error (e.g., bug) which caused ed to panic.\n"
"\nReport bugs to bug-ed@gnu.org\n"
"Ed home page: http://www.gnu.org/software/ed/ed.html\n"
"General help using GNU software: http://www.gnu.org/gethelp\n" );
@@ -107,7 +109,7 @@ static void show_version( void )
void show_strerror( const char * const filename, const int errcode )
{
- if( !scripted_ )
+ if( !quiet_ )
{
if( filename && filename[0] ) fprintf( stderr, "%s: ", filename );
fprintf( stderr, "%s\n", strerror( errcode ) );
@@ -127,11 +129,12 @@ static void show_error( const char * const msg, const int errcode, const bool he
}
-/* return true if file descriptor is a regular file */
-bool is_regular_file( const int fd )
+/* Return true if stdin is not a regular file.
+ Piped scripts count as interactive (do not force ed to exit on error). */
+bool interactive()
{
struct stat st;
- return ( fstat( fd, &st ) != 0 || S_ISREG( st.st_mode ) );
+ return fstat( 0, &st ) == 0 && !S_ISREG( st.st_mode );
}
@@ -161,9 +164,10 @@ int main( const int argc, const char * const argv[] )
{ 'h', "help", ap_no },
{ 'l', "loose-exit-status", ap_no },
{ 'p', "prompt", ap_yes },
+ { 'q', "quiet", ap_no },
+ { 'q', "silent", ap_no },
{ 'r', "restricted", ap_no },
- { 's', "quiet", ap_no },
- { 's', "silent", ap_no },
+ { 's', "script", ap_no },
{ 'v', "verbose", ap_no },
{ 'V', "version", ap_no },
{ opt_cr, "strip-trailing-cr", ap_no },
@@ -189,6 +193,7 @@ int main( const int argc, const char * const argv[] )
case 'h': show_help(); return 0;
case 'l': loose = true; break;
case 'p': if( set_prompt( arg ) ) break; else return 1;
+ case 'q': quiet_ = true; break;
case 'r': restricted_ = true; break;
case 's': scripted_ = true; break;
case 'v': set_verbose(); break;
@@ -208,14 +213,15 @@ int main( const int argc, const char * const argv[] )
if( strcmp( arg, "-" ) == 0 ) { scripted_ = true; ++argind; continue; }
if( may_access_filename( arg ) )
{
+ /* this read can't be undone because u_current_addr = u_last_addr = -1 */
const int ret = read_file( arg, 0 );
- if( ret < 0 && is_regular_file( 0 ) ) return 2;
+ if( ret < 0 && !interactive() ) return 2;
if( arg[0] != '!' && !set_def_filename( arg ) ) return 1;
if( ret == -2 ) initial_error = true;
}
else
{
- if( is_regular_file( 0 ) ) return 2;
+ if( !interactive() ) return 2;
initial_error = true;
}
break;
diff --git a/main_loop.c b/main_loop.c
index 61b8dd0..79804b3 100644
--- a/main_loop.c
+++ b/main_loop.c
@@ -1,6 +1,6 @@
/* GNU ed - The GNU line editor.
- Copyright (C) 1993, 1994 Andrew Moore, Talke Studio
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 1993, 1994 Andrew L. Moore, Talke Studio
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -48,6 +48,7 @@ bool set_def_filename( const char * const s )
static char * buf = 0; /* filename buffer */
static int bufsz = 0; /* filename buffer size */
const int len = strlen( s );
+
if( !resize_buffer( &buf, &bufsz, len + 1 ) ) return false;
memcpy( buf, s, len + 1 );
def_filename = buf;
@@ -65,6 +66,7 @@ bool set_prompt( const char * const s )
static char * buf = 0; /* prompt buffer */
static int bufsz = 0; /* prompt buffer size */
const int len = strlen( s );
+
if( !resize_buffer( &buf, &bufsz, len + 1 ) ) return false;
memcpy( buf, s, len + 1 );
prompt_str = buf;
@@ -132,13 +134,10 @@ static const char * get_shell_command( const char ** const ibufpp )
{
if( **ibufpp == '%' ) /* replace '%' with the default filename */
{
- const char * p;
if( !def_filename[0] ) { set_error_msg( no_cur_fn ); return 0; }
- p = strip_escapes( def_filename );
- if( !p ) return 0;
- len = strlen( p );
+ len = strlen( def_filename );
if( !resize_buffer( &buf, &bufsz, i + len ) ) return 0;
- memcpy( buf + i, p, len );
+ memcpy( buf + i, def_filename, len );
i += len; ++*ibufpp; replacement = true;
}
else /* copy char or escape sequence unescaping any '%' */
@@ -159,10 +158,9 @@ static const char * get_shell_command( const char ** const ibufpp )
}
-static const char * skip_blanks( const char * p )
+static void skip_blanks( const char ** const ibufpp )
{
- while( isspace( (unsigned char)*p ) && *p != '\n' ) ++p;
- return p;
+ while( isspace( (unsigned char)**ibufpp ) && **ibufpp != '\n' ) ++*ibufpp;
}
@@ -175,7 +173,7 @@ static const char * get_filename( const char ** const ibufpp,
const int pmax = path_max( 0 );
int n;
- *ibufpp = skip_blanks( *ibufpp );
+ skip_blanks( ibufpp );
if( **ibufpp != '\n' )
{
int size = 0;
@@ -196,27 +194,18 @@ static const char * get_filename( const char ** const ibufpp,
/* convert a string to int with out_of_range detection */
-static bool parse_int( int * const i, const char * const str,
- const char ** const tail )
+static bool parse_int( int * const i, const char ** const ibufpp )
{
- char * tmp;
- long li;
-
+ char * tail;
errno = 0;
- *i = li = strtol( str, &tmp, 10 );
- if( tail ) *tail = tmp;
- if( tmp == str )
- {
- set_error_msg( "Bad numerical result" );
- *i = 0;
- return false;
- }
+ const long li = strtol( *ibufpp, &tail, 10 );
+
+ if( tail == *ibufpp )
+ { set_error_msg( "Invalid number" ); return false; }
if( errno == ERANGE || li > INT_MAX || li < -INT_MAX )
- {
- set_error_msg( "Numerical result out of range" );
- *i = 0;
- return false;
- }
+ { set_error_msg( "Number out of range" ); return false; }
+ *ibufpp = tail;
+ *i = li;
return true;
}
@@ -231,7 +220,7 @@ static int extract_addresses( const char ** const ibufpp )
bool first = true; /* true == addr, false == offset */
first_addr = second_addr = -1; /* set to undefined */
- *ibufpp = skip_blanks( *ibufpp );
+ skip_blanks( ibufpp );
while( true )
{
@@ -239,18 +228,18 @@ static int extract_addresses( const char ** const ibufpp )
const unsigned char ch = **ibufpp;
if( isdigit( ch ) )
{
- if( !parse_int( &n, *ibufpp, ibufpp ) ) return -1;
+ if( !parse_int( &n, ibufpp ) ) return -1;
if( first ) { first = false; second_addr = n; } else second_addr += n;
}
else switch( ch )
{
case '\t':
- case ' ': *ibufpp = skip_blanks( ++*ibufpp ); break;
+ case ' ': ++*ibufpp; skip_blanks( ibufpp ); break;
case '+':
case '-': if( first ) { first = false; second_addr = current_addr(); }
if( isdigit( (unsigned char)(*ibufpp)[1] ) )
{
- if( !parse_int( &n, *ibufpp, ibufpp ) ) return -1;
+ if( !parse_int( &n, ibufpp ) ) return -1;
second_addr += n;
}
else { ++*ibufpp;
@@ -378,8 +367,7 @@ static bool get_command_s_suffix( const char ** const ibufpp,
if( ch >= '1' && ch <= '9' )
{
int n = 0;
- if( rep || !parse_int( &n, *ibufpp, ibufpp ) || n <= 0 )
- { error = true; break; }
+ if( rep || !parse_int( &n, ibufpp ) || n <= 0 ) { error = true; break; }
rep = true; *snump = n; continue;
}
else if( ch == 'g' )
@@ -431,7 +419,7 @@ static bool command_s( const char ** const ibufpp, int * const pflagsp,
if( **ibufpp >= '1' && **ibufpp <= '9' )
{
int n = 0;
- if( ( sflags & sf_g ) || !parse_int( &n, *ibufpp, ibufpp ) || n <= 0 )
+ if( ( sflags & sf_g ) || !parse_int( &n, ibufpp ) || n <= 0 )
error = true;
else
{ sflags |= sf_g; snum = n; }
@@ -451,7 +439,7 @@ static bool command_s( const char ** const ibufpp, int * const pflagsp,
if( error ) { set_error_msg( inv_com_suf ); return false; }
}
while( sflags && **ibufpp != '\n' );
- if( sflags )
+ if( sflags ) /* repeat last substitution */
{
if( !subst_regex() ) { set_error_msg( no_prev_subst ); return false; }
if( ( sflags & sf_r ) && !replace_subst_re_by_search_re() ) return false;
@@ -494,7 +482,7 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
const int addr_cnt = extract_addresses( ibufpp );
if( addr_cnt < 0 ) return ERR;
- *ibufpp = skip_blanks( *ibufpp );
+ skip_blanks( ibufpp );
c = *(*ibufpp)++;
switch( c )
{
@@ -524,11 +512,12 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
fnp = get_filename( ibufpp, false );
if( !fnp || !delete_lines( 1, last_addr(), isglobal ) ||
!close_sbuf() ) return ERR;
+ set_modified( false ); /* buffer is now empty */
if( !open_sbuf() ) return FATAL;
if( fnp[0] && fnp[0] != '!' && !set_def_filename( fnp ) )
return ERR;
if( read_file( fnp[0] ? fnp : def_filename, 0 ) < 0 ) return ERR;
- reset_undo_state(); set_modified( false );
+ reset_undo_state(); /* to prevent undoing the read */
break;
case 'f': if( unexpected_address( addr_cnt ) ||
unexpected_command_suffix( **ibufpp ) ) return ERR;
@@ -537,11 +526,7 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
if( fnp[0] == '!' )
{ set_error_msg( "Invalid redirection" ); return ERR; }
if( fnp[0] && !set_def_filename( fnp ) ) return ERR;
- {
- const char * const stripped_name = strip_escapes( def_filename );
- if( !stripped_name ) return ERR;
- printf( "%s\n", stripped_name );
- }
+ printf( "%s\n", def_filename );
break;
case 'g':
case 'v':
@@ -664,7 +649,7 @@ pflabel: if( !check_addr_range2( addr_cnt ) ||
case 'z': if( !check_second_addr( current_addr() + !isglobal, addr_cnt ) )
return ERR;
if( **ibufpp > '0' && **ibufpp <= '9' )
- { if( parse_int( &n, *ibufpp, ibufpp ) ) set_window_lines( n );
+ { if( parse_int( &n, ibufpp ) ) set_window_lines( n );
else return ERR; }
if( !get_command_suffix( ibufpp, &pflags ) ||
!print_lines( second_addr,
@@ -752,12 +737,6 @@ static int exec_global( const char ** const ibufpp, const int pflags,
}
-static void script_error( void )
- {
- if( verbose ) fprintf( stderr, "script, line %d: %s\n", linenum(), errmsg );
- }
-
-
int main_loop( const bool initial_error, const bool loose )
{
extern jmp_buf jmp_state;
@@ -790,8 +769,9 @@ int main_loop( const bool initial_error, const bool loose )
fputs( "?\n", stdout ); /* give warning */
if( !loose && err_status == 0 ) err_status = 1;
if( status == EMOD ) set_error_msg( "Warning: buffer modified" );
- if( is_regular_file( 0 ) )
- { script_error(); return ( ( status == FATAL ) ? 1 : err_status ); }
+ if( !interactive() )
+ { if( verbose ) printf( "script, line %d: %s\n", linenum(), errmsg );
+ return ( ( status == FATAL ) ? 1 : err_status ); }
if( status == FATAL )
{ if( verbose ) { printf( "%s\n", errmsg ); } return 1; }
}
diff --git a/regex.c b/regex.c
index 9b38120..abd0161 100644
--- a/regex.c
+++ b/regex.c
@@ -1,7 +1,7 @@
/* regex.c: regular expression interface routines for the ed line editor. */
/* GNU ed - The GNU line editor.
- Copyright (C) 1993, 1994 Andrew Moore, Talke Studio
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 1993, 1994 Andrew L. Moore, Talke Studio
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/signal.c b/signal.c
index 4f3a11a..7b0f45f 100644
--- a/signal.c
+++ b/signal.c
@@ -1,7 +1,7 @@
/* signal.c: signal and miscellaneous routines for the ed line editor. */
/* GNU ed - The GNU line editor.
- Copyright (C) 1993, 1994 Andrew Moore, Talke Studio
- Copyright (C) 2006-2022 Antonio Diaz Diaz.
+ Copyright (C) 1993, 1994 Andrew L. Moore, Talke Studio
+ Copyright (C) 2006-2023 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -139,7 +139,7 @@ int window_columns( void ) { return window_columns_; }
int window_lines( void ) { return window_lines_; }
-/* assure at least a minimum size for buffer 'buf' */
+/* assure at least a minimum size for buffer 'buf' up to INT_MAX - 1 */
bool resize_buffer( char ** const buf, int * const size, const unsigned min_size )
{
if( (unsigned)*size < min_size )
@@ -147,7 +147,7 @@ bool resize_buffer( char ** const buf, int * const size, const unsigned min_size
if( min_size >= INT_MAX )
{ set_error_msg( "Line too long" ); return false; }
const int new_size = ( ( min_size < 512 ) ? 512 :
- ( min_size > INT_MAX / 2 ) ? INT_MAX : ( min_size / 512 ) * 1024 );
+ ( min_size >= INT_MAX / 2 ) ? INT_MAX - 1 : ( min_size / 512 ) * 1024 );
void * new_buf = 0;
disable_interrupts();
if( *buf ) new_buf = realloc( *buf, new_size );
@@ -161,18 +161,3 @@ bool resize_buffer( char ** const buf, int * const size, const unsigned min_size
}
return true;
}
-
-
-/* return unescaped copy of escaped string */
-const char * strip_escapes( const char * p )
- {
- static char * buf = 0;
- static int bufsz = 0;
- const int len = strlen( p );
- int i = 0;
-
- if( !resize_buffer( &buf, &bufsz, len + 1 ) ) return 0;
- /* assert: no trailing escape */
- while( ( buf[i++] = ( ( *p == '\\' ) ? *++p : *p ) ) ) ++p;
- return buf;
- }
diff --git a/testsuite/a.ed b/testsuite/a.ed
index 314edc3..08a2bdb 100644
--- a/testsuite/a.ed
+++ b/testsuite/a.ed
@@ -30,6 +30,10 @@ u
a
hello world!!!!!
.
+# match the first line
+0;/^hello world!!!$/a
+second line
+.
a
to be undone
.
diff --git a/testsuite/a.r b/testsuite/a.r
index 9434d34..33cc2bb 100644
--- a/testsuite/a.r
+++ b/testsuite/a.r
@@ -1,4 +1,5 @@
hello world!!!
+second line
shell escape marker
This natural inequality of the two powers of population and of
production in the earth, and that great law of our nature which must
diff --git a/testsuite/check.sh b/testsuite/check.sh
index a876571..5198fa6 100755
--- a/testsuite/check.sh
+++ b/testsuite/check.sh
@@ -1,6 +1,6 @@
#! /bin/sh
# check script for GNU ed - The GNU line editor
-# Copyright (C) 2006-2022 Antonio Diaz Diaz.
+# Copyright (C) 2006-2023 Antonio Diaz Diaz.
#
# This script is free software; you have unlimited permission
# to copy, distribute, and modify it.
diff --git a/testsuite/filter.ed b/testsuite/filter.ed
new file mode 100644
index 0000000..d055104
--- /dev/null
+++ b/testsuite/filter.ed
@@ -0,0 +1,6 @@
+H
+6,10w !sort > tmp.txt 2>&1
+10r tmp.txt
+6,10d
+!rm tmp.txt
+wq out.o
diff --git a/testsuite/filter.r b/testsuite/filter.r
new file mode 100644
index 0000000..f387d5b
--- /dev/null
+++ b/testsuite/filter.r
@@ -0,0 +1,13 @@
+This natural inequality of the two powers of population and of
+production in the earth, and that great law of our nature which must
+constantly keep their effects equal, form the great difficulty that to
+me appears insurmountable in the way to the perfectibility of society.
+All other arguments are of slight and subordinate consideration in
+agrarian regulations in their utmost extent, could remove the pressure
+comparison of this. I see no way by which man can escape from the weight
+decisive against the possible existence of a society, all the members of
+of it even for a single century. And it appears, therefore, to be
+of this law which pervades all animated nature. No fancied equality, no
+which should live in ease, happiness, and comparative leisure; and feel
+no anxiety about providing the means of subsistence for themselves and
+their families.
diff --git a/testsuite/g.ed b/testsuite/g.ed
index 5514868..d35cd5a 100644
--- a/testsuite/g.ed
+++ b/testsuite/g.ed
@@ -10,7 +10,7 @@ order\
.\
# and in the command list \
i\
-caos\
+chaos\
.\
-1s/l/L
u
@@ -24,7 +24,7 @@ hello world\
# don't change current address if no match
g/xxx/1d
;j
-g/help! world/I/caos/d\
+g/help! world/I/chaos/d\
-;/order/;d
# split lines
g/./s/hello world/hello\
diff --git a/testsuite/g.r b/testsuite/g.r
index 0483355..0ed8179 100644
--- a/testsuite/g.r
+++ b/testsuite/g.r
@@ -9,7 +9,7 @@ heLp! world
of it even for a single century. And it appears, therefore, to be
hello
world
-caos
+chaos
agrarian regulations in their utmost extent, could remove the pressure
heLp! world
of this law which pervades all hello
@@ -18,11 +18,11 @@ heLp! world
comparison of this. I see no way by which man can escape from the weight
hello
world
-caos
+chaos
All other arguments are of slight and subordinate consideration in
hello
world
-caos
+chaos
me appears insurmountable in the way to the perfectibility of society.
heLp! world
constantly keep their effects equal, form the great hello
diff --git a/testsuite/w.ed b/testsuite/w.ed
index ce32199..dc6e2a8 100644
--- a/testsuite/w.ed
+++ b/testsuite/w.ed
@@ -1,7 +1,10 @@
H
-5w \!.z
+5w ./!.z
6W ./!.z
0r !cat < ./!.z
-r \!.z
+r ./!.z
!rm -f ./!.z
+15w \x2dhyphen\x2dprefixed\x2dfile
+r \x2dhyphen\x2dprefixed\x2dfile
+!rm -f '\x2dhyphen\x2dprefixed\x2dfile'
wq out.o
diff --git a/testsuite/w.r b/testsuite/w.r
index 9157ecb..c07a46a 100644
--- a/testsuite/w.r
+++ b/testsuite/w.r
@@ -15,3 +15,4 @@ no anxiety about providing the means of subsistence for themselves and
their families.
All other arguments are of slight and subordinate consideration in
comparison of this. I see no way by which man can escape from the weight
+their families.