From 10ca1c6c925d4ce2f2e0a38c45e05b39daeab2be Mon Sep 17 00:00:00 2001 From: Andrew Moore Date: Sat, 26 Jun 1993 06:47:21 +0000 Subject: [PATCH] fixed undo within a global command (would corrupt the buffer) changed move within a global to behave as in SunOS added a couple error messages --- bin/ed/POSIX | 12 ++++++++++++ bin/ed/buf.c | 6 +++++- bin/ed/ed.1 | 30 +++++++++++++++++------------- bin/ed/ed.h | 4 ++-- bin/ed/re.c | 2 +- bin/ed/test/g3.d | 5 +++++ bin/ed/test/g3.r | 5 +++++ bin/ed/test/g3.t | 4 ++++ bin/ed/test/g4.d | 5 +++++ bin/ed/test/g4.r | 7 +++++++ bin/ed/test/g4.t | 13 +++++++++++++ 11 files changed, 76 insertions(+), 17 deletions(-) create mode 100644 bin/ed/test/g3.d create mode 100644 bin/ed/test/g3.r create mode 100644 bin/ed/test/g3.t create mode 100644 bin/ed/test/g4.d create mode 100644 bin/ed/test/g4.r create mode 100644 bin/ed/test/g4.t diff --git a/bin/ed/POSIX b/bin/ed/POSIX index dd506fb5a606..47a80b9e72a0 100644 --- a/bin/ed/POSIX +++ b/bin/ed/POSIX @@ -48,3 +48,15 @@ Though ed is not a binary editor, it can be used (if painfully) 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. + +Since the behavior of `u' (undo) within a `g' (global) command list is +not specified by POSIX D11/2, it follows the behavior of the SunOS ed +(this is the best way, I think, in that the alternatives are either too +complicated to implement or too confusing to use): undo forces a global +command list to be executed only once, rather than for each line matching +a global pattern. In addtion, each instance of `u' within a global command +undoes all previous commands (including undo's) in the command list. + +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 +`active' list. diff --git a/bin/ed/buf.c b/bin/ed/buf.c index 57c336121ca1..1d74cb827f4a 100644 --- a/bin/ed/buf.c +++ b/bin/ed/buf.c @@ -165,7 +165,11 @@ getaddr(lp) while (cp != lp && (cp = cp->next) != &line0) n++; - return (cp != &line0) ? n : 0; + if (n && cp == &line0) { + sprintf(errmsg, "invalid address"); + return ERR; + } + return n; } diff --git a/bin/ed/ed.1 b/bin/ed/ed.1 index ff6a8499ffc4..e9a318080b39 100644 --- a/bin/ed/ed.1 +++ b/bin/ed/ed.1 @@ -92,9 +92,9 @@ commands have the structure: .I [address [,address]]command[parameters] .RE .sp -The address(es) indicate the line(s) to be affected by the command. -If fewer addresses are given than the command accepts, then default -addresses are supplied. +The address(es) indicate the line or range of lines to be affected by the +command. If fewer addresses are given than the command accepts, then +default addresses are supplied. .SS OPTIONS .TP 8 @@ -311,7 +311,7 @@ not listed below, including `{', '}', `(', `)', `<' and `>', matches itself. .TP 8 -\fR\\\fIc\fR +\fR\e\fIc\fR Any backslash-escaped character .IR c , except for `{', '}', `(', `)', `<' and `>', @@ -389,28 +389,28 @@ anchors the regular expression to the end of a line. Otherwise, it matches itself. .TP 8 -\fR\\<\fR +\fR\e<\fR Anchors the single character regular expression or subexpression immediately following it to the beginning of a word. (This may not be available) .TP 8 -\fR\\>\fR +\fR\e>\fR Anchors the single character regular expression or subexpression immediately following it to the end of a word. (This may not be available) .TP 8 -\fR\\(\fIre\fR\\)\fR +\fR\e(\fIre\fR\e)\fR Defines a subexpression .IR re . Subexpressions may be nested. -A subsequent backreference of the form \fI`\\n'\fR, where +A subsequent backreference of the form \fI`\en'\fR, where .I n is a number in the range [1,9], expands to the text matched by the .IR n th subexpression. -For example, the regular expression `\\(.*\\)\\1' matches any string +For example, the regular expression `\e(.*\e)\e1' matches any string consisting of identical adjacent substrings. Subexpressions are ordered relative to their left delimiter. @@ -426,7 +426,7 @@ the string `abbb' (as opposed to the substring `bbb'), since a null match is the only left-most match. .TP 8 -\fR\\{\fIn,m\fR\\}\fR or \fR\\{\fIn,\fR\\}\fR or \fR\\{\fIn\fR\\}\fR +\fR\e{\fIn,m\fR\e}\fR or \fR\e{\fIn,\fR\e}\fR or \fR\e{\fIn\fR\e}\fR Matches the single character regular expression or subexpression immediately preceding it at least .I n @@ -735,7 +735,7 @@ An unescaped `&' in .I replacement is replaced by the currently matched text. The character sequence -\fI`\\m'\fR, +\fI`\em'\fR, where .I m is a number in the range [1,9], is replaced by the @@ -912,8 +912,8 @@ that line. Buffer file .PD 0 .TP 20 -\fR./ed.hup\fR, $HOME/ed.hup -First and second files to which +ed.hup +The file to which .B ed attempts to write the buffer if the terminal hangs up. @@ -971,6 +971,10 @@ replaces any occurrences of .I old with .IR new . +If the +.I `u' +(undo) command occurs in a global command list, then +the command list is executed only once. If diagnostics are not disabled, attempting to quit .B ed diff --git a/bin/ed/ed.h b/bin/ed/ed.h index 1b277fe9359d..c854364dfb69 100644 --- a/bin/ed/ed.h +++ b/bin/ed/ed.h @@ -237,7 +237,7 @@ void lpqueue __P((line_t *)); void makekey __P((char *)); char *makesub __P((int)); char *translit __P((char *, int, int, int)); -int move __P((long)); +int move __P((long, int)); int oddesc __P((char *, char *)); void onhup __P((int)); void onintr __P((int)); @@ -253,7 +253,7 @@ int catsub __P((char *, regmatch_t *, int)); int subst __P((pattern_t *, int)); int tobinhex __P((int, int)); int transfer __P((long)); -int undo __P((void)); +int undo __P((int)); undo_t *upush __P((int, long, long)); void ureset __P((void)); diff --git a/bin/ed/re.c b/bin/ed/re.c index 462c816626f2..e94475033922 100644 --- a/bin/ed/re.c +++ b/bin/ed/re.c @@ -71,7 +71,7 @@ optpat() sprintf(errmsg, "invalid pattern delimiter"); return NULL; } else if (*ibufp == delim) { - sprintf(errmsg, "no previous pattern"); + if (!exp) sprintf(errmsg, "no previous pattern"); return exp; } else if ((exps = getlhs(delim)) == NULL) return NULL; diff --git a/bin/ed/test/g3.d b/bin/ed/test/g3.d new file mode 100644 index 000000000000..92f337e977f2 --- /dev/null +++ b/bin/ed/test/g3.d @@ -0,0 +1,5 @@ +line 1 +line 2 +line 3 +line 4 +line5 diff --git a/bin/ed/test/g3.r b/bin/ed/test/g3.r new file mode 100644 index 000000000000..cc6fbddec23b --- /dev/null +++ b/bin/ed/test/g3.r @@ -0,0 +1,5 @@ +linc 3 +xine 1 +xine 2 +xinc 4 +xinc5 diff --git a/bin/ed/test/g3.t b/bin/ed/test/g3.t new file mode 100644 index 000000000000..2d052a6e840d --- /dev/null +++ b/bin/ed/test/g3.t @@ -0,0 +1,4 @@ +g/./s//x/\ +3m0 +g/./s/e/c/\ +2,3m1 diff --git a/bin/ed/test/g4.d b/bin/ed/test/g4.d new file mode 100644 index 000000000000..92f337e977f2 --- /dev/null +++ b/bin/ed/test/g4.d @@ -0,0 +1,5 @@ +line 1 +line 2 +line 3 +line 4 +line5 diff --git a/bin/ed/test/g4.r b/bin/ed/test/g4.r new file mode 100644 index 000000000000..350882d82375 --- /dev/null +++ b/bin/ed/test/g4.r @@ -0,0 +1,7 @@ +hello +zine 1 +line 2 +line 3 +line 4 +line5 +world diff --git a/bin/ed/test/g4.t b/bin/ed/test/g4.t new file mode 100644 index 000000000000..ec618166cc37 --- /dev/null +++ b/bin/ed/test/g4.t @@ -0,0 +1,13 @@ +g/./s/./x/\ +u\ +s/./y/\ +u\ +s/./z/\ +u +u +0a +hello +. +$a +world +.