* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* This code is derived from software contributed to Berkeley by
* Rodney Ruddock of the University of Guelph.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* 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
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)g.c 8.1 (Berkeley) 5/31/93";
static int find_line
__P((LINE
*));
static void w_cmd_l_file
__P((FILE *, FILE *, int *));
* Find a line that we noted matched the RE earlier in the current
* buffer (it may have disappeared because of the commands in the
* Write the command line to a STDIO tmp file. See g() below.
* This allows us to use cmd_loop to run the command list because
* we "trick" cmd_loop into reading a STDIO file instead of stdin.
w_cmd_l_file(fp
, inputt
, errnum
)
int sl
=0, jmp_flag
, l_cnt
=0;
if (jmp_flag
= setjmp(ctrl_position3
))
else if ((ss
== '\\') && (sl
== '\\')) {
if ((sl
== '\n') || (sl
== EOF
))
* The global function. All global commands (g, G, v, and V) are handled
* in here. The lines to be affected by the command list are 1st noted
* and then the command list is invoked for each line matching the RE.
* Note the trick of how the command list is executed. Saves a lot of
* code (and allows for \n's in substitutions).
static char *l_template_g
;
static int l_template_flag
= 0;
int l_re_success
, l_flag_v
= 0, l_err
, l_num
;
register LINE
**l_gut
=gut
;
if (Start_default
&& End_default
) {
strcpy(help_msg
, "buffer empty");
if (l_template_flag
== 0) {
l_template_g
= calloc(FILENAME_LEN
, sizeof(char));
if (sigint_flag
&& (!sigspecial
))
if (l_template_g
== NULL
) {
strcpy(help_msg
, "out of memory error");
/* set up the STDIO command list file */
memmove(l_template_g
, "/tmp/_4.4bsd_ed_g_XXXXXX\0", 24);
if ((ss
== 'v') || (ss
== 'V'))
if ((ss
== 'G') || (ss
== 'V')) {
* If it's an interactive global command we use stdin, not a
if ((l_fp
= fopen(l_template_g
, "w+")) == NULL
) {
perror("ed: file I/O error, save buffer in ed.hup");
do_hup(); /* does not return */
if (sigint_flag
&& (!sigspecial
))
/* Get the RE for the global command. */
l_patt
= get_pattern(ss
, inputt
, errnum
, 0);
/* Instead of: if ((*errnum == -1) && (ss == '\n'))... */
if ((l_patt
[1] == '\0') && (RE_flag
== 0)) {
if (l_patt
[1] || (RE_patt
== NULL
)) {
if (sigint_flag
&& (!sigspecial
))
RE_sol
= (RE_patt
[1] == '^') ? 1 : 0;
(regfree(&RE_comp
), l_err
= regcomp(&RE_comp
, &RE_patt
[1], 0))) {
regerror(l_err
, &RE_comp
, help_msg
, 128);
if ((l_num
= line_number(bottom
)) > gut_num
) {
gut
= l_gut
= malloc(sizeof(LINE
**) * gut_num
);
strcpy(help_msg
, "out of memory error");
* Find the lines in the buffer that the global command wants
get_line(current
->handle
, current
->len
);
if (sigint_flag
&& (!sigspecial
))
regexec(&RE_comp
, text
, (size_t) RE_SEC
, RE_match
, 0);
/* l_re_success=0 => success */
if ( (l_re_success
== 0 && l_flag_v
== 0) ||
(l_re_success
&& l_flag_v
)) {
l_gut
[l_gut_cnt
++] = current
;
current
= current
->below
;
if (sigint_flag
&& (!sigspecial
))
strcpy(help_msg
, "no matches found");
/* if non-interactive, get the command list */
w_cmd_l_file(l_fp
, inputt
, errnum
);
for (a
=0; a
<l_gut_cnt
; a
++) {
* Execute the command list on the lines that still exist that
* we indicated earlier that global wants to work with.
fseek(l_fp
, (off_t
)0, 0);
if (find_line(l_gut
[a
])) {
get_line(current
->handle
, current
->len
);
if ((GV_flag
== 1) && (*errnum
< 0)) {