summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-10-19 16:13:09 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-10-19 16:13:09 +0900
commit8bb61616966b94aaadf747ab312ea8fd3700afe6 (patch)
tree5fe0f32fa57330307d2e8ba0235641358853bbac
parentd34c01a5949925f95939a20e0379c9bb529d5fd5 (diff)
downloaded-8bb61616966b94aaadf747ab312ea8fd3700afe6.tar.gz
ed-8bb61616966b94aaadf747ab312ea8fd3700afe6.tar.bz2
ed-8bb61616966b94aaadf747ab312ea8fd3700afe6.zip
Imported Upstream version 1.16upstream/1.16
-rw-r--r--ChangeLog44
-rw-r--r--INSTALL12
-rw-r--r--NEWS29
-rw-r--r--README11
-rw-r--r--buffer.c2
-rw-r--r--carg_parser.c6
-rw-r--r--carg_parser.h8
-rwxr-xr-xconfigure12
-rw-r--r--doc/ed.14
-rw-r--r--doc/ed.info184
-rw-r--r--doc/ed.texi227
-rw-r--r--ed.h8
-rw-r--r--global.c2
-rw-r--r--io.c2
-rw-r--r--main.c14
-rw-r--r--main_loop.c55
-rw-r--r--regex.c10
-rw-r--r--signal.c2
-rwxr-xr-xtestsuite/check.sh4
-rw-r--r--testsuite/s.ed6
-rw-r--r--testsuite/s.r4
21 files changed, 347 insertions, 299 deletions
diff --git a/ChangeLog b/ChangeLog
index 6ebb606..c281506 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,12 +1,24 @@
+2020-02-20 Antonio Diaz Diaz <antonio@gnu.org>
+
+ * Version 1.16 released.
+ * regex.c (line_replace): Accept 's/^/#/g' as valid.
+ (Reported by Bjoern Wibben).
+ * main_loop.c: Removed length limit of prompt string.
+ (Reported by Tim Chase).
+ * main.c: Set a valid invocation_name even if argc == 0.
+ * ed.texi: Extended operators depend on regex implementation.
+ (Reported by Brian Zwahr).
+ * ed.texi: Several fixes and improvements.
+
2019-01-01 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.15 released.
- * io.c (print_line): Make 'l' command print '\\' before every
+ * io.c (print_line): Make command 'l' print '\\' before every
'$' within the text. (Reported by Ori Avtalion).
* main_loop.c (extract_addresses): Fixed address ',,' to mean
'$,$' instead of '1,$'. (Reported by Matthieu Felix).
* regex.c (extract_replacement): Allow newlines even if global.
- * main_loop.c (exec_command): Make 'c' command reject address 0.
+ * main_loop.c (exec_command): Make command 'c' reject address 0.
* ed.texi: Minor fixes.
* configure: Accept appending to CFLAGS, 'CFLAGS+=OPTIONS'.
@@ -31,14 +43,14 @@
'3 ---- 2' was calculated as -2 instead of 1.
Accept ranges with the first address omitted.
(exec_command): Fixed current address after empty replacement
- text in 'c' command.
+ text in command 'c'.
Don't clear the modified status after writing the buffer to a
shell command. (Reported by Jérôme Frgacic).
(get_command_suffix): Don't allow repeated print suffixes.
(command_s): Accept suffixes in any order.
Don't allow multiple count suffixes.
'sp' now toggles all print suffixes.
- (main_loop): Make EOF on stdin behave as a 'q' command.
+ (main_loop): Make EOF on stdin behave as command 'q'.
* ed.texi: Fixed the description of commands 'acegijkmqrsuw'.
Documented that ed allows any combination of print suffixes.
* testsuite: Improved most tests. Simplified bug reporting.
@@ -60,9 +72,9 @@
2015-03-30 Antonio Diaz Diaz <antonio@gnu.org>
* Version 1.11 released.
- * main_loop.c (exec_command): Fixed 'z' command.
+ * main_loop.c (exec_command): Fixed command 'z'.
(zN printed N + 1 lines).
- * ed.texi: Documented the window size used by the 'z' command.
+ * ed.texi: Documented the window size used by the command 'z'.
* Makefile.in: Added new targets 'install*-compress'.
* Restored original copyright notices in the code. I assigned to
the FSF the copyright on changes made to the part of ed already
@@ -97,8 +109,8 @@
2012-01-01 Antonio Diaz Diaz <ant_diaz@teleline.es>
* Version 1.6 released.
- * io.c (put_tty_line): Null characters where incorrectly
- shown by the 'l' command. (Reported by Martin Guy).
+ * io.c (put_tty_line): Null characters where incorrectly shown
+ by the command 'l'. (Reported by Martin Guy).
* io.c (read_stream): Corrected the condition deciding when to
show the message "Newline appended".
* main_loop.c (exec_command): The 'modified' flag is now set
@@ -118,16 +130,16 @@
2010-08-30 Antonio Diaz Diaz <ant_diaz@teleline.es>
* Version 1.5 released.
- * buffer.c (append_lines): Fixed 'a', 'c' and 'i' commands.
+ * buffer.c (append_lines): Fixed commands 'a', 'c' and 'i'.
(When used in a global command list, the commands following
them in the list were ignored).
- * main_loop.c (exec_command): Fixed 'e' command.
+ * main_loop.c (exec_command): Fixed command 'e'.
(It quitted when invoked a second time with a modified buffer).
* main.c: Added new option '-r, --restricted'.
* 'red' has been converted to a script invoking 'ed --restricted'.
* Description of ed in the manual has been changed.
* testsuite: Modified some tests and removed obsolete POSIX tests.
- * main_loop.c: 'ibufp' variable made local to main_loop.
+ * main_loop.c: Variable 'ibufp' made local to main_loop.
* Defined type bool to make clear which functions and variables
are Boolean.
* Added 'const' to all pointer declarations accepting it.
@@ -143,8 +155,8 @@
* buffer.c, main_loop.c: Undo now restores the modified status.
* regex.c (search_and_replace): Fixed a race condition with user
interrupt.
- * signal.c: Added functions resize_line_buffer and
- resize_undo_buffer to definitively fix the aliasing warnings.
+ * signal.c: Added new functions 'resize_line_buffer' and
+ 'resize_undo_buffer' to definitively fix the aliasing warnings.
* Some minor corrections have been made to the manual.
2009-05-24 Antonio Diaz Diaz <ant_diaz@teleline.es>
@@ -217,7 +229,7 @@
* Version 0.3 released.
* buffer.c (open_sbuf): Fixed symlink vulnerability using 'tmpfile'.
* signal.c: Fixed signal handling for SIGINT.
- * main_loop.c (exec_command): Modified 'c' and 'i' commands to
+ * main_loop.c (exec_command): Modified commands 'c' and 'i' to
treat address 0 a synonym for address 1, as per POSIX.
* The pause mode has been removed.
* main.c: Added new option '-l, --loose-exit-status'.
@@ -279,8 +291,8 @@ Dec 1993 François Pinard <pinard@icule>
Copyright (C) 1993 François Pinard
Copyright (C) 1994 Andrew Moore
-Copyright (C) 2006-2019 Antonio Diaz Diaz.
+Copyright (C) 2006-2020 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
+but just in case, you have unlimited permission to copy, distribute, and
modify it.
diff --git a/INSTALL b/INSTALL
index a1ec4df..aaf7569 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
Requirements
------------
You will need a C compiler and a C library compatible with GNU libc.
-I use gcc 5.3.0 and 4.1.2, but the code should compile with any standards
+I use gcc 6.1.0 and 4.1.2, but the code should compile with any standards
compliant compiler.
Gcc is available at http://gcc.gnu.org.
@@ -44,10 +44,10 @@ the main archive.
Another way
-----------
You can also compile ed into a separate directory.
-To do this, you must use a version of 'make' that supports the 'VPATH'
-variable, such as GNU 'make'. 'cd' to the directory where you want the
+To do this, you must use a version of 'make' that supports the variable
+'VPATH', such as GNU 'make'. 'cd' to the directory where you want the
object files and executables to go and run the 'configure' script.
-'configure' automatically checks for the source code in '.', in '..' and
+'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
@@ -58,7 +58,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above.
-Copyright (C) 2006-2019 Antonio Diaz Diaz.
+Copyright (C) 2006-2020 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
-distribute and modify it.
+distribute, and modify it.
diff --git a/NEWS b/NEWS
index a50306b..b2f4b21 100644
--- a/NEWS
+++ b/NEWS
@@ -1,24 +1,13 @@
-Changes in version 1.15:
+Changes in version 1.16:
-The list command has been fixed to print a backslash before every '$'
-character within the text. (Reported by Ori Avtalion).
+The substitute command no longer complains about an 'Infinite substitution
+loop' with a substitution like 's/^/#/g'. (Reported by Bjoern Wibben).
-Address ',,' has been fixed to mean '$,$' instead of '1,$'.
-(Reported by Matthieu Felix).
+The length limit of the prompt string has been removed.
+(Reported by Tim Chase).
-A 's' command that is part of a 'g' or 'v' command-list can again split
-a line by including a newline escaped with a backslash '\' in the
-replacement string. For this to work, the closing delimiter of the
-replacement string can't be omitted unless the 's' command is the last
-command in the list, because otherwise the meaning of the escaped
-newline would become ambiguous.
+It has been documented in the manual that extended regular expression
+operators may be unavailable depending on the particular regex
+implementation in the system running ed. (Reported by Brian Zwahr).
-Following a recent change in the POSIX standard, the 'c' command no
-longer accepts an address of 0, and the documentation for the 'i'
-command now explains that it treats address 0 as meaning "at the
-beginning of the buffer", instead of as a synonym for address 1.
-
-Minor fixes have been made to the manual.
-
-The configure script now accepts appending options to CFLAGS using the
-syntax 'CFLAGS+=OPTIONS'.
+Several fixes and improvements have been made to the manual.
diff --git a/README b/README
index 96ccd02..fc52ed2 100644
--- a/README
+++ b/README
@@ -35,8 +35,9 @@ EXTENSIONS
* Though GNU ed is not a stream editor, it can be used to edit binary files.
To assist in binary editing, when a file containing at least one ASCII
NUL character is written, a newline is not appended if it did not
- already contain one upon reading. In particular, reading /dev/null
- prior to writing prevents appending a newline to a binary file.
+ already contain one upon reading. 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.
For example, to create a file with GNU ed containing a single NUL character:
$ ed file
@@ -92,7 +93,7 @@ DEVIATIONS
to use.
* The 'm' (move) command within a 'g' command list also follows the SunOS
- ed implementation: any moved lines are removed from the global command's
+ ed implementation: any lines moved are removed from the global command's
'active' list.
* For backwards compatibility, errors in piped scripts do not force ed
@@ -127,10 +128,10 @@ or:
Copyright (C) 1993, 1994 Andrew Moore
-Copyright (C) 2006-2019 Antonio Diaz Diaz.
+Copyright (C) 2006-2020 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy,
-distribute and modify it.
+distribute, and modify it.
The file Makefile.in is a data file used by configure to produce the
Makefile. It has the same copyright owner and permissions that configure
diff --git a/buffer.c b/buffer.c
index e2bb31e..0a000be 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-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 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/carg_parser.c b/carg_parser.c
index ce01d7b..27d1a71 100644
--- a/carg_parser.c
+++ b/carg_parser.c
@@ -1,15 +1,15 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
- Copyright (C) 2006-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 Antonio Diaz Diaz.
This library is free software. 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.
+ 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
+ notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
This library is distributed in the hope that it will be useful,
diff --git a/carg_parser.h b/carg_parser.h
index dcae2de..60472ef 100644
--- a/carg_parser.h
+++ b/carg_parser.h
@@ -1,15 +1,15 @@
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
- Copyright (C) 2006-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 Antonio Diaz Diaz.
This library is free software. 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.
+ 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
+ notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
This library is distributed in the hope that it will be useful,
@@ -18,7 +18,7 @@
*/
/* Arg_parser reads the arguments in 'argv' and creates a number of
- option codes, option arguments and non-option arguments.
+ option codes, option arguments, and non-option arguments.
In case of error, 'ap_error' returns a non-null pointer to an error
message.
diff --git a/configure b/configure
index 671897c..4594825 100755
--- a/configure
+++ b/configure
@@ -1,12 +1,12 @@
#! /bin/sh
# configure script for GNU ed - The GNU line editor
-# Copyright (C) 2006-2019 Antonio Diaz Diaz.
+# Copyright (C) 2006-2020 Antonio Diaz Diaz.
#
# This configure script is free software: you have unlimited permission
-# to copy, distribute and modify it.
+# to copy, distribute, and modify it.
pkgname=ed
-pkgversion=1.15
+pkgversion=1.16
progname=ed
srctrigger=doc/${pkgname}.texi
@@ -152,7 +152,7 @@ if [ -z "${no_create}" ] ; then
# Run this file to recreate the current configuration.
#
# This script is free software: you have unlimited permission
-# to copy, distribute and modify it.
+# to copy, distribute, and modify it.
exec /bin/sh $0 ${args} --no-create
EOF
@@ -175,11 +175,11 @@ echo "LDFLAGS = ${LDFLAGS}"
rm -f Makefile
cat > Makefile << EOF
# Makefile for GNU ed - The GNU line editor
-# Copyright (C) 2006-2019 Antonio Diaz Diaz.
+# Copyright (C) 2006-2020 Antonio Diaz Diaz.
# This file was generated automatically by configure. Don't edit.
#
# This Makefile is free software: you have unlimited permission
-# to copy, distribute and modify it.
+# to copy, distribute, and modify it.
pkgname = ${pkgname}
pkgversion = ${pkgversion}
diff --git a/doc/ed.1 b/doc/ed.1
index d7dc057..05d5b6f 100644
--- a/doc/ed.1
+++ b/doc/ed.1
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
-.TH ED "1" "January 2019" "ed 1.15" "User Commands"
+.TH ED "1" "February 2020" "ed 1.16" "User Commands"
.SH NAME
ed \- line-oriented text editor
.SH SYNOPSIS
@@ -55,7 +55,7 @@ General help using GNU software: http://www.gnu.org/gethelp
.SH COPYRIGHT
Copyright \(co 1994 Andrew L. Moore.
.br
-Copyright \(co 2019 Antonio Diaz Diaz.
+Copyright \(co 2020 Antonio Diaz Diaz.
License GPLv3+: GNU GPL version 3 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 34bd7f9..1fe73bb 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-2019 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 2006-2020 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
@@ -18,16 +18,7 @@ File: ed.info, Node: Top, Next: Overview, Up: (dir)
The GNU ed line editor
**********************
-This manual is for GNU ed (version 1.15, 1 January 2019).
-
-
- GNU ed is a line-oriented text editor. It is used to create, display,
-modify and otherwise manipulate text files, both interactively and via
-shell scripts. A restricted version of ed, red, can only edit files in
-the current directory and cannot execute shell commands. Ed is the
-'standard' text editor in the sense that it is the original editor for
-Unix, and thus widely available. For most purposes, however, it is
-superseded by full-screen editors such as GNU Emacs or GNU Moe.
+This manual is for GNU ed (version 1.16, 20 February 2020).
* Menu:
@@ -43,7 +34,7 @@ superseded by full-screen editors such as GNU Emacs or GNU Moe.
* GNU Free Documentation License:: How you can copy and share this manual
- Copyright (C) 1993, 1994, 2006-2019 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 2006-2020 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
@@ -56,10 +47,17 @@ File: ed.info, Node: Overview, Next: Introduction to line editing, Prev: Top,
1 Overview
**********
-'ed' is a line-oriented text editor. It is used to create, display,
-modify and otherwise manipulate text files. 'red' is a restricted 'ed':
-it can only edit files in the current directory and cannot execute
-shell commands.
+GNU ed is a line-oriented text editor. It is used to create, display,
+modify and otherwise manipulate text files, both interactively and via
+shell scripts. A restricted version of ed, red, can only edit files in
+the current directory and cannot execute shell commands. Ed is the
+'standard' text editor in the sense that it is the original editor for
+Unix, and thus widely available. For most purposes, however, it is
+superseded by full-screen editors such as GNU Emacs or GNU Moe.
+
+ GNU ed is based on the editor algorithm described in Brian W.
+Kernighan and P. J. Plauger's book "Software Tools in Pascal",
+Addison-Wesley, 1981.
If invoked with a FILE argument, then a copy of FILE is read into
the editor's buffer. Changes are made to this copy and not directly to
@@ -345,8 +343,8 @@ prefixed with a bang.
'-p STRING'
'--prompt=STRING'
- Specifies a command prompt. This may be toggled on and off with the
- 'P' command.
+ Specifies a command prompt string and turns prompting on. Showing
+ the prompt string may be toggled on and off with the 'P' command.
'-r'
'--restricted'
@@ -389,8 +387,8 @@ and is valid wherever it makes sense.
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. The value of the first address in a range cannot exceed the
-value of the second.
+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
@@ -448,7 +446,7 @@ requires zero addresses.
''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 portable character set.
+ from the portable character set '[a-z]'.
Addresses can be followed by one or more address offsets, optionally
@@ -527,7 +525,7 @@ that point is matched.
[=COL-ELM=]
where COL-ELM is a "collating element" are interpreted according
- to 'locale (5)'. See 'regex (3)' for an explanation of these
+ to 'locale (5)'. See 'regex (7)' for an explanation of these
constructs.
'[^CHAR-CLASS]'
@@ -582,8 +580,10 @@ that point is matched.
underscore (_).
- The following extended operators are preceded by a backslash '\' to
-distinguish them from traditional 'ed' syntax.
+ The following extended regular expression operators are preceded by a
+backslash '\' to distinguish them from traditional 'ed' syntax. They
+may be unavailable depending on the particular regex implementation in
+your system.
'\`'
'\''
@@ -638,6 +638,10 @@ command. It is not portable to give more than one print suffix, but
their effects. If any suffix letter is given, it must immediately
follow the command.
+ The 'e', 'E', 'f', 'r', and 'w' commands take an optional FILE
+parameter, separated from the command letter by one or more whitespace
+characters.
+
An interrupt (typically <Control-C>) has the effect of aborting the
current command and returning the editor to command mode.
@@ -655,12 +659,13 @@ specified (in parenthesis).
'(.,.)c'
Changes lines in the buffer. The addressed lines are deleted from
the buffer, and text is inserted in their place. Text is entered
- in input mode. The current address is set to the address of the
+ in input mode. The current address is set to the address of the
last line entered or, if there were none, to the new address of
the line after the last line deleted; if the lines deleted were
originally at the end of the buffer, the current address is set to
the address of the new last line; if no lines remain in the
- buffer, the current address is set to zero.
+ buffer, the current address is set to zero. The lines deleted are
+ copied to the cut buffer.
'(.,.)d'
Deletes the addressed lines from the buffer. The current address
@@ -668,6 +673,7 @@ specified (in parenthesis).
if the lines deleted were originally at the end of the buffer, the
current address is set to the address of the new last line; if no
lines remain in the buffer, the current address is set to zero.
+ The lines deleted are copied to the cut buffer.
'e FILE'
Edits FILE, and sets the default filename. If FILE is not
@@ -704,12 +710,13 @@ specified (in parenthesis).
unchanged.
The first command of COMMAND-LIST must appear on the same line as
- the 'g' command. All lines of a multi-line COMMAND-LIST except the
+ the 'g' command. The other commands of COMMAND-LIST must appear on
+ separate lines. All lines of a multi-line COMMAND-LIST except the
last line must be terminated with a backslash ('\'). Any commands
are allowed, except for 'g', 'G', 'v', and 'V'. The '.'
terminating the input mode of commands 'a', 'c', and 'i' can be
- omitted if it would be the last line of COMMAND-LIST. By default,
- a newline alone in COMMAND-LIST is equivalent to a 'p' command. If
+ omitted if it would be the last line of COMMAND-LIST. By default, a
+ newline alone in COMMAND-LIST is equivalent to a 'p' command. If
'ed' is invoked with the command-line option '-G', then a newline
in COMMAND-LIST is equivalent to a '.+1p' command.
@@ -726,7 +733,7 @@ specified (in parenthesis).
the last non-null command list.
'h'
- Prints an explanation of the last error.
+ Help. Prints an explanation of the last error.
'H'
Toggles the printing of error explanations. By default,
@@ -743,9 +750,9 @@ specified (in parenthesis).
'(.,.+1)j'
Joins the addressed lines, replacing them by a single line
containing their joined text. If only one address is given, this
- command does nothing. If lines are joined, the current address is
- set to the address of the joined line. Else, the current address
- is unchanged.
+ command does nothing. If lines are joined, the lines replaced are
+ copied to the cut buffer and the current address is set to the
+ address of the joined line. Else, the current address is unchanged.
'(.)kx'
Marks a line with a lower case letter 'x'. The line can then be
@@ -765,8 +772,8 @@ specified (in parenthesis).
the right-hand destination address. The destination address '0'
(zero) is valid for this command; it moves the addressed lines to
the beginning of the buffer. It is an error if the destination
- address falls within the range of moved lines. The current address
- is set to the new address of the last line moved.
+ address falls within the range of lines to be moved. The current
+ address is set to the new address of the last line moved.
'(.,.)n'
Number command. Prints the addressed lines, preceding each line by
@@ -778,9 +785,10 @@ specified (in parenthesis).
address of the last line printed.
'P'
- Toggles the command prompt on and off. Unless a prompt is
- specified with command-line option '-p', the command prompt is by
- default turned off.
+ Toggles the command prompt on and off. Unless a prompt string is
+ specified with the command-line option '-p', the command prompt is
+ by default turned off. The default prompt string is an asterisk
+ ('*').
'q'
Quits 'ed'. A warning is printed if any changes have been made in
@@ -807,20 +815,21 @@ specified (in parenthesis).
unchanged.
'(.,.)s/RE/REPLACEMENT/'
- Substitute command. Replaces text in the addressed lines matching a
- regular expression RE with REPLACEMENT. By default, only the first
- match in each line is replaced. The 's' command accepts any
- combination of the suffixes 'g', 'COUNT', 'l', 'n', and 'p'. If
- the 'g' (global) suffix is given, then every match is replaced.
- The 'COUNT' suffix, where COUNT is a positive number, causes only
- the COUNTth match to be replaced. 'g' and 'COUNT' can't be
- specified in the same command. 'l', 'n', and 'p' are the usual
- print suffixes. It is an error if no substitutions are performed
- on any of the addressed lines. The current address is set to the
- address of the last line on which a substitution occurred. If a
- line is split, a substitution is considered to have occurred on
- each of the new lines. If no substitution is performed, the
- current address is unchanged.
+ Substitute command. Replaces text in the addressed lines matching
+ a regular expression RE with REPLACEMENT. By default, only the
+ first match in each line is replaced. The 's' command accepts any
+ combination of the suffixes 'g', 'COUNT', 'l', 'n', and 'p'. If
+ the 'g' (global) suffix is given, then every match is replaced. The
+ 'COUNT' suffix, where COUNT is a positive number, causes only the
+ COUNTth match to be replaced. 'g' and 'COUNT' can't be specified
+ in the same command. 'l', 'n', and 'p' are the usual print
+ suffixes. It is an error if no substitutions are performed on any
+ of the addressed lines. The current address is set to the address
+ of the last line on which a substitution occurred. If a line is
+ split, a substitution is considered to have occurred on each of
+ the new lines. If no substitution is performed, the 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'
@@ -860,10 +869,11 @@ specified (in parenthesis).
current address is set to the address of the last line copied.
'u'
- Undoes the effect of the last command that modified anything in the
- buffer and restores the current address to what it was before the
- command. The global commands 'g', 'G', 'v', and 'V' are treated as
- a single command by undo. 'u' is its own inverse.
+ Undoes the effect of the last command that modified anything in
+ the buffer and restores the current address to what it was before
+ the command. The global commands 'g', 'G', 'v', and 'V' are
+ treated as a single command by undo. 'u' is its own inverse; it
+ can undo only the last command.
'(1,$)v/RE/COMMAND-LIST'
This is similar to the 'g' command except that it applies
@@ -876,9 +886,9 @@ specified (in parenthesis).
'(1,$)w FILE'
Writes the addressed lines to FILE. Any previous contents of FILE
- is lost without warning. If there is no default filename, then the
- default filename is set to FILE, otherwise it is unchanged. If no
- filename is specified, then the default filename is used. The
+ are lost without warning. If there is no default filename, then
+ the default filename is set to FILE, otherwise it is unchanged. If
+ no filename is specified, then the default filename is used. The
current address is unchanged.
If FILE is prefixed with a bang (!), then it is interpreted as a
@@ -895,7 +905,7 @@ specified (in parenthesis).
'(1,$)W FILE'
Appends the addressed lines to the end of FILE. This is similar to
- the 'w' command, except that the previous contents of file is not
+ the 'w' command, except that the previous contents of FILE are not
clobbered. The current address is unchanged.
'(.)x'
@@ -909,11 +919,11 @@ specified (in parenthesis).
commands. The current address is unchanged.
'(.+1)zN'
- Scrolls N lines at a time starting at addressed line, and sets
- window size to N. If N is not specified, then the current window
- size is used. Window size defaults to screen size minus two lines,
- or to 22 if screen size can't be determined. The current address
- is set to the address of the last line printed.
+ Scroll. Prints N lines at a time starting at addressed line, and
+ sets window size to N. If N is not specified, then the current
+ window size is used. Window size defaults to screen size minus two
+ lines, or to 22 if screen size can't be determined. The current
+ address is set to the address of the last line printed.
'!COMMAND'
Shell escape command. Executes COMMAND via 'sh (1)'. If the first
@@ -951,13 +961,21 @@ If the terminal hangs up, 'ed' attempts to write the buffer to the file
'ed' processes FILE arguments for backslash escapes, i.e., in a
filename, any character preceded by a backslash ('\') is interpreted
-literally.
-
- 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.
-
- Per line overhead: 2 'pointer's, 1 'long int', and 1 'int'.
+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 prevents appending a newline to a binary
+file.
+
+ In order to keep track of the text lines in the buffer, 'ed' uses a
+doubly linked list of structures containing the position and size of
+each line. This results in a per line overhead of 2 'pointer's, 1 'long
+int', and 1 'int'.

File: ed.info, Node: Diagnostics, Next: Problems, Prev: Limitations, Up: Top
@@ -1482,17 +1500,17 @@ permit their use in free software.

Tag Table:
Node: Top535
-Node: Overview2194
-Node: Introduction to line editing4250
-Node: Invoking ed11523
-Node: Line addressing13589
-Node: Regular expressions17231
-Node: Commands22829
-Ref: shell escape command36677
-Node: Limitations37699
-Node: Diagnostics38344
-Node: Problems38989
-Node: GNU Free Documentation License39522
+Node: Overview1710
+Node: Introduction to line editing4175
+Node: Invoking ed11448
+Node: Line addressing13565
+Node: Regular expressions17267
+Node: Commands22974
+Ref: shell escape command37385
+Node: Limitations38407
+Node: Diagnostics39499
+Node: Problems40144
+Node: GNU Free Documentation License40677

End Tag Table
diff --git a/doc/ed.texi b/doc/ed.texi
index 913f7fa..0e0faf5 100644
--- a/doc/ed.texi
+++ b/doc/ed.texi
@@ -6,8 +6,8 @@
@finalout
@c %**end of header
-@set UPDATED 1 January 2019
-@set VERSION 1.15
+@set UPDATED 20 February 2020
+@set VERSION 1.16
@dircategory Basics
@direntry
@@ -15,7 +15,7 @@
@end direntry
@copying
-Copyright @copyright{} 1993, 1994, 2006-2019 Free Software Foundation, Inc.
+Copyright @copyright{} 1993, 1994, 2006-2020 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
@@ -43,15 +43,6 @@ Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
@top The GNU ed line editor
This manual is for GNU ed (version @value{VERSION}, @value{UPDATED}).
-
-@sp 1
-GNU ed is a line-oriented text editor. It is used to create, display,
-modify and otherwise manipulate text files, both interactively and via
-shell scripts. A restricted version of ed, red, can only edit files in
-the current directory and cannot execute shell commands. Ed is the
-'standard' text editor in the sense that it is the original editor for
-Unix, and thus widely available. For most purposes, however, it is
-superseded by full-screen editors such as GNU Emacs or GNU Moe.
@end ifnottex
@menu
@@ -74,10 +65,16 @@ superseded by full-screen editors such as GNU Emacs or GNU Moe.
@node Overview
@chapter Overview
-@command{ed} is a line-oriented text editor. It is used to create,
-display, modify and otherwise manipulate text files. @command{red} is a
-restricted @command{ed}: it can only edit files in the current directory
-and cannot execute shell commands.
+@uref{http://www.gnu.org/software/ed/ed.html,,GNU ed} is a line-oriented
+text editor. It is used to create, display, modify and otherwise manipulate
+text files, both interactively and via shell scripts. A restricted version
+of ed, red, can only edit files in the current directory and cannot execute
+shell commands. Ed is the 'standard' text editor in the sense that it is the
+original editor for Unix, and thus widely available. For most purposes,
+however, it is superseded by full-screen editors such as GNU Emacs or GNU Moe.
+
+GNU ed is based on the editor algorithm described in Brian W. Kernighan and
+P. J. Plauger's book "Software Tools in Pascal", Addison-Wesley, 1981.
If invoked with a @var{file} argument, then a copy of @var{file} is read
into the editor's buffer. Changes are made to this copy and not directly
@@ -151,8 +148,7 @@ is made, it can be corrected immediately, before more damage is done.
Editing in @command{ed} requires more strategy and forethought; but if
you are up to the task, it can be quite efficient.
-Much of the @command{ed} command syntax is shared with other Unix
-utilities.
+Much of the @command{ed} command syntax is shared with other Unix utilities.
As with the shell, @key{RETURN} (the carriage-return key) enters a line
of input. So when we speak of "entering" a command or some text in
@@ -222,7 +218,7 @@ Mo Tu We Th Fr Sa Su
*
@end example
-Now let's write the buffer contents to a file named @code{junk} with the
+Now let's write the buffer contents to a file named @samp{junk} with the
@key{w} (@dfn{write}) command:
@example
@@ -300,9 +296,8 @@ Subsequent commands affect only the selected line, a.k.a. the
@dfn{current} line. Portions of that line are then replaced with the
substitute command, whose syntax is @samp{s/@var{old}/@var{new}/}.
-Although @command{ed} accepts only one command per line, the print
-command @samp{p} is an exception, and may be appended to the end of most
-commands.
+Although @command{ed} accepts only one command per line, the print command
+@samp{p} is an exception, and may be appended to the end of most commands.
In the next example, a title is added to our sonnet.
@@ -341,8 +336,7 @@ 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:
+@command{regex (3)}, @command{sh (1)}. Relevant documents are:
@quotation
Unix User's Manual Supplementary Documents: 12 --- 13
@@ -398,8 +392,8 @@ when @command{ed} is invoked as the editor for crontab.
@item -p @var{string}
@itemx --prompt=@var{string}
-Specifies a command prompt. This may be toggled on and off with the
-@samp{P} command.
+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 -r
@itemx --restricted
@@ -438,12 +432,12 @@ 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.
-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. The value of the first address in a range cannot exceed the
-value of the second.
+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
@@ -503,7 +497,7 @@ necessary.
@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.
+the portable character set @samp{[a-z]}.
@end table
@@ -590,22 +584,20 @@ If @samp{-} appears as the first or last character of @var{char-class},
then it matches itself. All other characters in @var{char-class} match
themselves.
-Patterns in
-@var{char-class}
-of the form:
+Patterns in @var{char-class} of the form:
@example
[.@var{col-elm}.]
[=@var{col-elm}=]
@end example
@noindent
-where @var{col-elm} is a @dfn{collating element} are interpreted
-according to @code{locale (5)}. See
-@code{regex (3)} for an explanation of these constructs.
+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
+constructs.
@item [^@var{char-class}]
-Matches any single character, other than newline, not in
-@var{char-class}. @var{char-class} is defined as above.
+Matches any single character, other than newline, not in @var{char-class}.
+@var{char-class} is defined as above.
@item ^
If @samp{^} is the first character of a regular expression, then it
@@ -656,8 +648,10 @@ maximal string of alphanumeric characters, including the underscore (_).
@end table
-The following extended operators are preceded by a backslash @samp{\} to
-distinguish them from traditional @command{ed} syntax.
+The following extended regular expression operators are preceded by a
+backslash @samp{\} to distinguish them from traditional @command{ed} syntax.
+They may be unavailable depending on the particular regex implementation in
+your system.
@table @code
@@ -713,6 +707,10 @@ suffix, but @command{ed} allows any combination of non-repeated print
suffixes and combines their effects. If any suffix letter is given, it
must immediately follow the command.
+The @samp{e}, @samp{E}, @samp{f}, @samp{r}, and @samp{w} commands take an
+optional @var{file} parameter, separated from the command letter by one or
+more whitespace characters.
+
An interrupt (typically @key{Control-C}) has the effect of aborting the
current command and returning the editor to command mode.
@@ -731,19 +729,21 @@ none, to the addressed line.
@item (.,.)c
Changes lines in the buffer. The addressed lines are deleted from the
-buffer, and text is inserted in their place. Text is entered in input
-mode. The current address is set to the address of the last line entered
-or, if there were none, to the new address of the line after the last
-line deleted; if the lines deleted were originally at the end of the
-buffer, the current address is set to the address of the new last line;
-if no lines remain in the buffer, the current address is set to zero.
+buffer, and text is inserted in their place. Text is entered in input mode.
+The current address is set to the address of the last line entered or, if
+there were none, to the new address of the line after the last line deleted;
+if the lines deleted were originally at the end of the buffer, the current
+address is set to the address of the new last line; if no lines remain in
+the buffer, the current address is set to zero. The lines deleted are copied
+to the cut buffer.
@item (.,.)d
-Deletes the addressed lines from the buffer. The current address is set
-to the new address of the line after the last line deleted; if the lines
-deleted were originally at the end of the buffer, the current address is
-set to the address of the new last line; if no lines remain in the
-buffer, the current address is set to zero.
+Deletes the addressed lines from the buffer. The current address is set to
+the new address of the line after the last line deleted; if the lines
+deleted were originally at the end of the buffer, the current address is set
+to the address of the new last line; if no lines remain in the buffer, the
+current address is set to zero. The lines deleted are copied to the cut
+buffer.
@item e @var{file}
Edits @var{file}, and sets the default filename. If @var{file} is not
@@ -777,16 +777,16 @@ final value of the current address is the value assigned by the last
command in the last @var{command-list} executed. If there were no
matching lines, the current address is unchanged.
-The first command of @var{command-list} must appear on the same line as
-the @samp{g} command. All lines of a multi-line @var{command-list}
-except the last line must be terminated with a backslash (@samp{\}). Any
-commands are 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 newline in @var{command-list} is
-equivalent to a @samp{.+1p} command.
+The first command of @var{command-list} must appear on the same line as the
+@samp{g} command. The other commands of @var{command-list} must appear on
+separate lines. All lines of a multi-line @var{command-list} except the last
+line must be terminated with a backslash (@samp{\}). Any commands are
+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
+newline in @var{command-list} is equivalent to a @samp{.+1p} command.
@item (1,$)G/@var{re}/
Interactive global command. Interactively edits the addressed lines
@@ -801,7 +801,7 @@ command. A newline alone acts as a null command list. A single @samp{&}
repeats the last non-null command list.
@item h
-Prints an explanation of the last error.
+Help. Prints an explanation of the last error.
@item H
Toggles the printing of error explanations. By default, explanations are
@@ -816,10 +816,11 @@ address is set to the address of the last line entered or, if there were
none, to the addressed line.
@item (.,.+1)j
-Joins the addressed lines, replacing them by a single line containing
-their joined text. If only one address is given, this command does
-nothing. If lines are joined, the current address is set to the address
-of the joined line. Else, the current address is unchanged.
+Joins the addressed lines, replacing them by a single line containing their
+joined text. If only one address is given, this command does nothing. If
+lines are joined, the lines replaced are copied to the cut buffer and the
+current address is set to the address of the joined line. Else, the current
+address is unchanged.
@item (.)kx
Marks a line with a lower case letter @samp{x}. The line can then be
@@ -839,8 +840,8 @@ Moves lines in the buffer. The addressed lines are moved to after the
right-hand destination address. The destination address @samp{0} (zero)
is valid for this command; it moves the addressed lines to the beginning
of the buffer. It is an error if the destination address falls within
-the range of moved lines. The current address is set to the new address
-of the last line moved.
+the range of lines to be moved. The current address is set to the new
+address of the last line moved.
@item (.,.)n
Number command. Prints the addressed lines, preceding each line by its
@@ -852,9 +853,9 @@ Prints the addressed lines. The current address is set to the address of
the last line printed.
@item P
-Toggles the command prompt on and off. Unless a prompt is specified with
-command-line option @samp{-p}, the command prompt is by default turned
-off.
+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
+turned off. The default prompt string is an asterisk (@samp{*}).
@item q
Quits @command{ed}. A warning is printed if any changes have been made
@@ -862,7 +863,7 @@ in the buffer since the last @samp{w} command that wrote the entire
buffer to a file.
@item Q
-Quits @command{ed} unconditionally. This is similar to the @code{q}
+Quits @command{ed} unconditionally. This is similar to the @samp{q}
command, except that unwritten changes are discarded without warning.
@item ($)r @var{file}
@@ -879,20 +880,20 @@ shell command whose output is to be read, (@pxref{shell escape command}
@samp{!} below). In this case the default filename is unchanged.
@item (.,.)s/@var{re}/@var{replacement}/
-Substitute command. Replaces text in the addressed lines matching a
-regular expression @var{re} with @var{replacement}. By default, only the
-first match in each line is replaced. The @samp{s} command accepts any
-combination of the suffixes @samp{g}, @samp{@var{count}}, @samp{l},
-@samp{n}, and @samp{p}. If the @samp{g} (global) suffix is given, then
-every match is replaced. The @samp{@var{count}} suffix, where
-@var{count} is a positive number, causes only the @var{count}th match to
-be replaced. @samp{g} and @samp{@var{count}} can't be specified in the
-same command. @samp{l}, @samp{n}, and @samp{p} are the usual print
-suffixes. It is an error if no substitutions are performed on any of the
-addressed lines. The current address is set to the address of the last
-line on which a substitution occurred. If a line is split, a
-substitution is considered to have occurred on each of the new lines. If
-no substitution is performed, the current address is unchanged.
+Substitute command. Replaces text in the addressed lines matching a regular
+expression @var{re} with @var{replacement}. By default, only the first match
+in each line is replaced. The @samp{s} command accepts any combination of
+the suffixes @samp{g}, @samp{@var{count}}, @samp{l}, @samp{n}, and @samp{p}.
+If the @samp{g} (global) suffix is given, then every match is replaced. The
+@samp{@var{count}} suffix, where @var{count} is a positive number, causes
+only the @var{count}th match to be replaced. @samp{g} and @samp{@var{count}}
+can't be specified in the same command. @samp{l}, @samp{n}, and @samp{p} are
+the usual print suffixes. It is an error if no substitutions are performed
+on any of the addressed lines. The current address is set to the address of
+the last line on which a substitution occurred. If a line is split, a
+substitution is considered to have occurred on each of the new lines. If no
+substitution is performed, the 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
@@ -933,10 +934,11 @@ lines are copied at the beginning of the buffer. The current address is
set to the address of the last line copied.
@item u
-Undoes the effect of the last command that modified anything in the
-buffer and restores the current address to what it was before the
-command. The global commands @samp{g}, @samp{G}, @samp{v}, and @samp{V}
-are treated as a single command by undo. @samp{u} is its own inverse.
+Undoes the effect of the last command that modified anything in the buffer
+and restores the current address to what it was before the command. The
+global commands @samp{g}, @samp{G}, @samp{v}, and @samp{V} are treated as a
+single command by undo. @samp{u} is its own inverse; it can undo only the
+last command.
@item (1,$)v/@var{re}/@var{command-list}
This is similar to the @samp{g} command except that it applies
@@ -949,7 +951,7 @@ edits the addressed lines not matching the regular expression @var{re}.
@item (1,$)w @var{file}
Writes the addressed lines to @var{file}. Any previous contents of
-@var{file} is lost without warning. If there is no default filename,
+@var{file} are lost without warning. If there is no default filename,
then the default filename is set to @var{file}, otherwise it is
unchanged. If no filename is specified, then the default filename is
used. The current address is unchanged.
@@ -966,8 +968,8 @@ Writes the addressed lines to @var{file}, and then executes a @samp{q}
command.
@item (1,$)W @var{file}
-Appends the addressed lines to the end of @var{file}. This is similar to
-the @samp{w} command, except that the previous contents of file is not
+Appends the addressed lines to the end of @var{file}. This is similar to the
+@samp{w} command, except that the previous contents of @var{file} are not
clobbered. The current address is unchanged.
@item (.)x
@@ -980,11 +982,11 @@ overwritten by subsequent @samp{c}, @samp{d}, @samp{j}, @samp{s}, or
@samp{y} commands. The current address is unchanged.
@item (.+1)z@var{n}
-Scrolls @var{n} lines at a time starting at addressed line, and sets
-window size to @var{n}. If @var{n} is not specified, then the current
-window size is used. Window size defaults to screen size minus two
-lines, or to 22 if screen size can't be determined. The current address
-is set to the address of the last line printed.
+Scroll. Prints @var{n} lines at a time starting at addressed line, and sets
+window size to @var{n}. If @var{n} is not specified, then the current window
+size is used. Window size defaults to screen size minus two lines, or to 22
+if screen size can't be determined. The current address is set to the
+address of the last line printed.
@anchor{shell escape command}
@item !@var{command}
@@ -1021,15 +1023,22 @@ set to the address of the printed line.
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.
+@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 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.
+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.
-Per line overhead: 2 @code{pointer}s, 1 @code{long int}, and 1 @code{int}.
+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
+line. This results in a per line overhead of 2 @samp{pointer}s, 1 @samp{long
+int}, and 1 @samp{int}.
@node Diagnostics
@@ -1058,7 +1067,7 @@ for all eternity, if not longer.
If you find a bug in @command{ed}, please send electronic mail to
@email{bug-ed@@gnu.org}. Include the version number, which you can
-find by running @w{@code{ed --version}}.
+find by running @w{@samp{ed --version}}.
@node GNU Free Documentation License
diff --git a/ed.h b/ed.h
index 0a51184..dafe674 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-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 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
@@ -117,9 +117,9 @@ bool traditional( void );
/* defined in main_loop.c */
int main_loop( const bool loose );
-void set_def_filename( const char * const s );
-void set_error_msg( const char * msg );
-void set_prompt( const char * const s );
+bool set_def_filename( const char * const s );
+void set_error_msg( const char * const msg );
+bool set_prompt( const char * const s );
void set_verbose( void );
void unmark_line_node( const line_t * const lp );
diff --git a/global.c b/global.c
index 9cec32c..09421c4 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-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 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/io.c b/io.c
index 953a56b..4e5da2e 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-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 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/main.c b/main.c
index 5b7e92d..6436f77 100644
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
/* GNU ed - The GNU line editor.
- Copyright (C) 2006-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 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
@@ -43,8 +43,8 @@
static const char * const program_name = "ed";
-static const char * const program_year = "2019";
-static const char * invocation_name = 0;
+static const char * const program_year = "2020";
+static const char * invocation_name = "ed"; /* default value */
static bool restricted_ = false; /* if set, run in restricted mode */
static bool scripted_ = false; /* if set, suppress diagnostics,
@@ -76,7 +76,7 @@ static void show_help( void )
" -r, --restricted run in restricted mode\n"
" -s, --quiet, --silent suppress diagnostics, byte counts and '!' prompt\n"
" -v, --verbose be verbose; equivalent to the 'H' command\n"
- "Start edit by reading in 'file' if given.\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"
@@ -159,7 +159,7 @@ int main( const int argc, const char * const argv[] )
{ 0 , 0, ap_no } };
struct Arg_parser parser;
- invocation_name = argv[0];
+ if( argc > 0 ) invocation_name = argv[0];
if( !ap_init( &parser, argc, argv, options, 0 ) )
{ show_error( "Memory exhausted.", 0, false ); return 1; }
@@ -176,7 +176,7 @@ int main( const int argc, const char * const argv[] )
case 'G': traditional_ = true; break; /* backward compatibility */
case 'h': show_help(); return 0;
case 'l': loose = true; break;
- case 'p': set_prompt( arg ); break;
+ case 'p': if( set_prompt( arg ) ) break; else return 1;
case 'r': restricted_ = true; break;
case 's': scripted_ = true; break;
case 'v': set_verbose(); break;
@@ -197,7 +197,7 @@ int main( const int argc, const char * const argv[] )
{
if( read_file( arg, 0 ) < 0 && is_regular_file( 0 ) )
return 2;
- else if( arg[0] != '!' ) set_def_filename( arg );
+ else if( arg[0] != '!' && !set_def_filename( arg ) ) return 1;
}
else
{
diff --git a/main_loop.c b/main_loop.c
index 5c15199..66858af 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-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 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
@@ -27,32 +27,41 @@
enum Status { QUIT = -1, ERR = -2, EMOD = -3, FATAL = -4 };
-static char def_filename[1024] = ""; /* default filename */
+static const char * def_filename = ""; /* default filename */
static char errmsg[80] = ""; /* error message buffer */
-static char prompt_str[80] = "*"; /* command prompt */
+static const char * prompt_str = "*"; /* command prompt */
static int first_addr = 0, second_addr = 0;
static bool prompt_on = false; /* if set, show command prompt */
static bool verbose = false; /* if set, print all error messages */
-void set_def_filename( const char * const s )
+bool set_def_filename( const char * const s )
{
- strncpy( def_filename, s, sizeof def_filename );
- def_filename[sizeof(def_filename)-1] = 0;
+ 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;
+ return true;
}
-void set_error_msg( const char * msg )
+void set_error_msg( const char * const msg )
{
- if( !msg ) msg = "";
strncpy( errmsg, msg, sizeof errmsg );
errmsg[sizeof(errmsg)-1] = 0;
}
-void set_prompt( const char * const s )
+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;
prompt_on = true;
- strncpy( prompt_str, s, sizeof prompt_str );
- prompt_str[sizeof(prompt_str)-1] = 0;
+ return true;
}
void set_verbose( void ) { verbose = true; }
@@ -445,7 +454,8 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
case 'd': if( !check_addr_range2( addr_cnt ) ||
!get_command_suffix( ibufpp, &pflags, 0 ) ) return ERR;
if( !isglobal ) clear_undo_stack();
- if( !delete_lines( first_addr, second_addr, isglobal ) ) return ERR;
+ if( !delete_lines( first_addr, second_addr, isglobal ) )
+ return ERR;
break;
case 'e': if( modified() && prev_status != EMOD ) return EMOD;
/* fall through */
@@ -455,9 +465,9 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
if( !fnp || !delete_lines( 1, last_addr(), isglobal ) ||
!close_sbuf() ) return ERR;
if( !open_sbuf() ) return FATAL;
- if( fnp[0] && fnp[0] != '!' ) set_def_filename( fnp );
- if( read_file( fnp[0] ? fnp : def_filename, 0 ) < 0 )
+ 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 );
break;
case 'f': if( unexpected_address( addr_cnt ) ||
@@ -466,7 +476,7 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
if( !fnp ) return ERR;
if( fnp[0] == '!' )
{ set_error_msg( "Invalid redirection" ); return ERR; }
- if( fnp[0] ) set_def_filename( fnp );
+ if( fnp[0] && !set_def_filename( fnp ) ) return ERR;
printf( "%s\n", strip_escapes( def_filename ) );
break;
case 'g':
@@ -480,8 +490,7 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
return ERR;
n = ( c == 'G' || c == 'V' ); /* interactive */
if( ( n && !get_command_suffix( ibufpp, &pflags, 0 ) ) ||
- !exec_global( ibufpp, pflags, n ) )
- return ERR;
+ !exec_global( ibufpp, pflags, n ) ) return ERR;
break;
case 'h':
case 'H': if( unexpected_address( addr_cnt ) ||
@@ -538,7 +547,8 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
if( addr_cnt == 0 ) second_addr = last_addr();
fnp = get_filename( ibufpp, false );
if( !fnp ) return ERR;
- if( !def_filename[0] && fnp[0] != '!' ) set_def_filename( fnp );
+ if( !def_filename[0] && fnp[0] != '!' && !set_def_filename( fnp ) )
+ return ERR;
if( !isglobal ) clear_undo_stack();
addr = read_file( fnp[0] ? fnp : def_filename, second_addr );
if( addr < 0 ) return ERR;
@@ -567,7 +577,8 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
first_addr = second_addr = 0;
else if( !check_addr_range( 1, last_addr(), addr_cnt ) )
return ERR;
- if( !def_filename[0] && fnp[0] != '!' ) set_def_filename( fnp );
+ if( !def_filename[0] && fnp[0] != '!' && !set_def_filename( fnp ) )
+ return ERR;
addr = write_file( fnp[0] ? fnp : def_filename,
( c == 'W' ) ? "a" : "w", first_addr, second_addr );
if( addr < 0 ) return ERR;
@@ -594,8 +605,7 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
if( !get_command_suffix( ibufpp, &pflags, 0 ) ||
!print_lines( second_addr,
min( last_addr(), second_addr + window_lines() - 1 ),
- pflags ) )
- return ERR;
+ pflags ) ) return ERR;
pflags = 0;
break;
case '=': if( !get_command_suffix( ibufpp, &pflags, 0 ) ) return ERR;
@@ -610,8 +620,7 @@ static int exec_command( const char ** const ibufpp, const int prev_status,
break;
case '\n': if( !check_second_addr( current_addr() +
( traditional() || !isglobal ), addr_cnt ) ||
- !print_lines( second_addr, second_addr, 0 ) )
- return ERR;
+ !print_lines( second_addr, second_addr, 0 ) ) return ERR;
break;
case '#': while( *(*ibufpp)++ != '\n' ) {}
break;
diff --git a/regex.c b/regex.c
index 316102f..cd4eb15 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-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 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
@@ -310,6 +310,7 @@ static int line_replace( char ** txtbufp, int * const txtbufszp,
if( !regexec( subst_regex_, txt, se_max, rm, 0 ) )
{
int matchno = 0;
+ bool infloop = false;
do {
if( global || snum == ++matchno )
{
@@ -329,13 +330,14 @@ static int line_replace( char ** txtbufp, int * const txtbufszp,
memcpy( *txtbufp + offset, txt, i ); offset += i;
}
txt += rm[0].rm_eo;
+ if( global && rm[0].rm_eo == 0 )
+ { if( !infloop ) infloop = true; /* 's/^/#/g' is valid */
+ else { set_error_msg( "Infinite substitution loop" ); return -1; } }
}
- while( *txt && ( !changed || ( global && rm[0].rm_eo ) ) &&
+ while( *txt && ( !changed || global ) &&
!regexec( subst_regex_, txt, se_max, rm, REG_NOTBOL ) );
i = eot - txt;
if( !resize_buffer( txtbufp, txtbufszp, offset + i + 2 ) ) return -1;
- if( global && i > 0 && !rm[0].rm_eo )
- { set_error_msg( "Infinite substitution loop" ); return -1; }
if( isbinary() ) newline_to_nul( txt, i );
memcpy( *txtbufp + offset, txt, i ); /* tail copy */
memcpy( *txtbufp + offset + i, "\n", 2 );
diff --git a/signal.c b/signal.c
index a352828..5df36d5 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-2019 Antonio Diaz Diaz.
+ Copyright (C) 2006-2020 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/testsuite/check.sh b/testsuite/check.sh
index 2a79a2f..c612d76 100755
--- a/testsuite/check.sh
+++ b/testsuite/check.sh
@@ -1,9 +1,9 @@
#! /bin/sh
# check script for GNU ed - The GNU line editor
-# Copyright (C) 2006-2019 Antonio Diaz Diaz.
+# Copyright (C) 2006-2020 Antonio Diaz Diaz.
#
# This script is free software; you have unlimited permission
-# to copy, distribute and modify it.
+# to copy, distribute, and modify it.
LC_ALL=C
export LC_ALL
diff --git a/testsuite/s.ed b/testsuite/s.ed
index a643f1e..7e1da83 100644
--- a/testsuite/s.ed
+++ b/testsuite/s.ed
@@ -52,6 +52,12 @@ s0e0103
(nature)/
+12s/ (for)/$\
(for)/
+6s/^/#/g
+6s/$/!\
+\
+/g
+7s,^,// line 7,g
+8s,^$,// line 8,g
# to be undone
,s/./x/g
u
diff --git a/testsuite/s.r b/testsuite/s.r
index c2b20b9..29a7963 100644
--- a/testsuite/s.r
+++ b/testsuite/s.r
@@ -3,7 +3,9 @@
(nature) (which) (must)$
^constantly keep th1ir_effects equal, form the great difficulty that to$
^m1 app1ars insurmountabl1 in th1 03 to th1 p1rf1ctibility of soci1ty.$
-hello world
+#hello world!
+// line 7
+// line 8
^All other arguments are of slight and subordinate consid1ration in$$
^(comparison) (of) (this.) (I) (see) (no) (03)$
(by) (which) (04) (can) (escape) (from) (the) (weight)$