1d165d4acSAndrew Moore /* glob.c: This file contains the global command routines for the ed line 2d165d4acSAndrew Moore editor */ 3d165d4acSAndrew Moore /*- 4d165d4acSAndrew Moore * Copyright (c) 1993 Andrew Moore, Talke Studio. 5d165d4acSAndrew Moore * All rights reserved. 6d165d4acSAndrew Moore * 7d165d4acSAndrew Moore * Redistribution and use in source and binary forms, with or without 8d165d4acSAndrew Moore * modification, are permitted provided that the following conditions 9d165d4acSAndrew Moore * are met: 10d165d4acSAndrew Moore * 1. Redistributions of source code must retain the above copyright 11d165d4acSAndrew Moore * notice, this list of conditions and the following disclaimer. 12d165d4acSAndrew Moore * 2. Redistributions in binary form must reproduce the above copyright 13d165d4acSAndrew Moore * notice, this list of conditions and the following disclaimer in the 14d165d4acSAndrew Moore * documentation and/or other materials provided with the distribution. 15d165d4acSAndrew Moore * 16d165d4acSAndrew Moore * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17d165d4acSAndrew Moore * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18d165d4acSAndrew Moore * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19d165d4acSAndrew Moore * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20d165d4acSAndrew Moore * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21d165d4acSAndrew Moore * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22d165d4acSAndrew Moore * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23d165d4acSAndrew Moore * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24d165d4acSAndrew Moore * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25d165d4acSAndrew Moore * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26d165d4acSAndrew Moore * SUCH DAMAGE. 27d165d4acSAndrew Moore */ 28d165d4acSAndrew Moore 29d165d4acSAndrew Moore #ifndef lint 30d165d4acSAndrew Moore static char *rcsid = "@(#)glob.c,v 1.1 1994/02/01 00:34:40 alm Exp"; 31d165d4acSAndrew Moore #endif /* not lint */ 32d165d4acSAndrew Moore 33d165d4acSAndrew Moore #include <sys/ioctl.h> 34d165d4acSAndrew Moore #include <sys/wait.h> 35d165d4acSAndrew Moore 36d165d4acSAndrew Moore #include "ed.h" 37d165d4acSAndrew Moore 38d165d4acSAndrew Moore 39d165d4acSAndrew Moore /* build_active_list: add line matching a pattern to the global-active list */ 40d165d4acSAndrew Moore int 41d165d4acSAndrew Moore build_active_list(isgcmd) 42d165d4acSAndrew Moore int isgcmd; 43d165d4acSAndrew Moore { 44d165d4acSAndrew Moore pattern_t *pat; 45d165d4acSAndrew Moore line_t *lp; 46d165d4acSAndrew Moore long n; 47d165d4acSAndrew Moore char *s; 48d165d4acSAndrew Moore char delimiter; 49d165d4acSAndrew Moore 50d165d4acSAndrew Moore if ((delimiter = *ibufp) == ' ' || delimiter == '\n') { 51d165d4acSAndrew Moore sprintf(errmsg, "invalid pattern delimiter"); 52d165d4acSAndrew Moore return ERR; 53d165d4acSAndrew Moore } else if ((pat = get_compiled_pattern()) == NULL) 54d165d4acSAndrew Moore return ERR; 55d165d4acSAndrew Moore else if (*ibufp == delimiter) 56d165d4acSAndrew Moore ibufp++; 57d165d4acSAndrew Moore clear_active_list(); 58d165d4acSAndrew Moore lp = get_addressed_line_node(first_addr); 59d165d4acSAndrew Moore for (n = first_addr; n <= second_addr; n++, lp = lp->q_forw) { 60d165d4acSAndrew Moore if ((s = get_sbuf_line(lp)) == NULL) 61d165d4acSAndrew Moore return ERR; 62d165d4acSAndrew Moore if (isbinary) 63d165d4acSAndrew Moore NUL_TO_NEWLINE(s, lp->len); 64d165d4acSAndrew Moore if (!regexec(pat, s, 0, NULL, 0) == isgcmd && 65d165d4acSAndrew Moore set_active_node(lp) < 0) 66d165d4acSAndrew Moore return ERR; 67d165d4acSAndrew Moore } 68d165d4acSAndrew Moore return 0; 69d165d4acSAndrew Moore } 70d165d4acSAndrew Moore 71d165d4acSAndrew Moore 72d165d4acSAndrew Moore /* exec_global: apply command list in the command buffer to the active 73d165d4acSAndrew Moore lines in a range; return command status */ 74d165d4acSAndrew Moore long 75d165d4acSAndrew Moore exec_global(interact, gflag) 76d165d4acSAndrew Moore int interact; 77d165d4acSAndrew Moore int gflag; 78d165d4acSAndrew Moore { 79d165d4acSAndrew Moore static char *ocmd = NULL; 80d165d4acSAndrew Moore static int ocmdsz = 0; 81d165d4acSAndrew Moore 82d165d4acSAndrew Moore line_t *lp = NULL; 83d165d4acSAndrew Moore int status; 84d165d4acSAndrew Moore int n; 85d165d4acSAndrew Moore char *cmd = NULL; 86d165d4acSAndrew Moore 87d165d4acSAndrew Moore #ifdef BACKWARDS 88d165d4acSAndrew Moore if (!interact) 89d165d4acSAndrew Moore if (!strcmp(ibufp, "\n")) 90d165d4acSAndrew Moore cmd = "p\n"; /* null cmd-list == `p' */ 91d165d4acSAndrew Moore else if ((cmd = get_extended_line(&n, 0)) == NULL) 92d165d4acSAndrew Moore return ERR; 93d165d4acSAndrew Moore #else 94d165d4acSAndrew Moore if (!interact && (cmd = get_extended_line(&n, 0)) == NULL) 95d165d4acSAndrew Moore return ERR; 96d165d4acSAndrew Moore #endif 97d165d4acSAndrew Moore clear_undo_stack(); 98d165d4acSAndrew Moore while ((lp = next_active_node()) != NULL) { 99d165d4acSAndrew Moore if ((current_addr = get_line_node_addr(lp)) < 0) 100d165d4acSAndrew Moore return ERR; 101d165d4acSAndrew Moore if (interact) { 102d165d4acSAndrew Moore /* print current_addr; get a command in global syntax */ 103d165d4acSAndrew Moore if (display_lines(current_addr, current_addr, gflag) < 0) 104d165d4acSAndrew Moore return ERR; 105d165d4acSAndrew Moore while ((n = get_tty_line()) > 0 && 106d165d4acSAndrew Moore ibuf[n - 1] != '\n') 107d165d4acSAndrew Moore clearerr(stdin); 108d165d4acSAndrew Moore if (n < 0) 109d165d4acSAndrew Moore return ERR; 110d165d4acSAndrew Moore else if (n == 0) { 111d165d4acSAndrew Moore sprintf(errmsg, "unexpected end-of-file"); 112d165d4acSAndrew Moore return ERR; 113d165d4acSAndrew Moore } else if (n == 1 && !strcmp(ibuf, "\n")) 114d165d4acSAndrew Moore continue; 115d165d4acSAndrew Moore else if (n == 2 && !strcmp(ibuf, "&\n")) { 116d165d4acSAndrew Moore if (cmd == NULL) { 117d165d4acSAndrew Moore sprintf(errmsg, "no previous command"); 118d165d4acSAndrew Moore return ERR; 119d165d4acSAndrew Moore } else cmd = ocmd; 120d165d4acSAndrew Moore } else if ((cmd = get_extended_line(&n, 0)) == NULL) 121d165d4acSAndrew Moore return ERR; 122d165d4acSAndrew Moore else { 123d165d4acSAndrew Moore REALLOC(ocmd, ocmdsz, n + 1, ERR); 124d165d4acSAndrew Moore memcpy(ocmd, cmd, n + 1); 125d165d4acSAndrew Moore cmd = ocmd; 126d165d4acSAndrew Moore } 127d165d4acSAndrew Moore 128d165d4acSAndrew Moore } 129d165d4acSAndrew Moore ibufp = cmd; 130d165d4acSAndrew Moore for (; *ibufp;) 131d165d4acSAndrew Moore if ((status = extract_addr_range()) < 0 || 132d165d4acSAndrew Moore (status = exec_command()) < 0 || 133d165d4acSAndrew Moore status > 0 && (status = display_lines( 134d165d4acSAndrew Moore current_addr, current_addr, status)) < 0) 135d165d4acSAndrew Moore return status; 136d165d4acSAndrew Moore } 137d165d4acSAndrew Moore return 0; 138d165d4acSAndrew Moore } 139d165d4acSAndrew Moore 140d165d4acSAndrew Moore 141d165d4acSAndrew Moore line_t **active_list; /* list of lines active in a global command */ 142d165d4acSAndrew Moore long active_last; /* index of last active line in active_list */ 143d165d4acSAndrew Moore long active_size; /* size of active_list */ 144d165d4acSAndrew Moore long active_ptr; /* active_list index (non-decreasing) */ 145d165d4acSAndrew Moore long active_ndx; /* active_list index (modulo active_last) */ 146d165d4acSAndrew Moore 147d165d4acSAndrew Moore /* set_active_node: add a line node to the global-active list */ 148d165d4acSAndrew Moore int 149d165d4acSAndrew Moore set_active_node(lp) 150d165d4acSAndrew Moore line_t *lp; 151d165d4acSAndrew Moore { 152d165d4acSAndrew Moore if (active_last + 1 > active_size) { 153d165d4acSAndrew Moore int ti = active_size; 154d165d4acSAndrew Moore line_t **ts; 155d165d4acSAndrew Moore SPL1(); 156d165d4acSAndrew Moore #if defined(sun) || defined(NO_REALLOC_NULL) 157d165d4acSAndrew Moore if (active_list != NULL) { 158d165d4acSAndrew Moore #endif 159d165d4acSAndrew Moore if ((ts = (line_t **) realloc(active_list, 160d165d4acSAndrew Moore (ti += MINBUFSZ) * sizeof(line_t **))) == NULL) { 161d165d4acSAndrew Moore fprintf(stderr, "%s\n", strerror(errno)); 162d165d4acSAndrew Moore sprintf(errmsg, "out of memory"); 163d165d4acSAndrew Moore SPL0(); 164d165d4acSAndrew Moore return ERR; 165d165d4acSAndrew Moore } 166d165d4acSAndrew Moore #if defined(sun) || defined(NO_REALLOC_NULL) 167d165d4acSAndrew Moore } else { 168d165d4acSAndrew Moore if ((ts = (line_t **) malloc((ti += MINBUFSZ) * 169d165d4acSAndrew Moore sizeof(line_t **))) == NULL) { 170d165d4acSAndrew Moore fprintf(stderr, "%s\n", strerror(errno)); 171d165d4acSAndrew Moore sprintf(errmsg, "out of memory"); 172d165d4acSAndrew Moore SPL0(); 173d165d4acSAndrew Moore return ERR; 174d165d4acSAndrew Moore } 175d165d4acSAndrew Moore } 176d165d4acSAndrew Moore #endif 177d165d4acSAndrew Moore active_size = ti; 178d165d4acSAndrew Moore active_list = ts; 179d165d4acSAndrew Moore SPL0(); 180d165d4acSAndrew Moore } 181d165d4acSAndrew Moore active_list[active_last++] = lp; 182d165d4acSAndrew Moore return 0; 183d165d4acSAndrew Moore } 184d165d4acSAndrew Moore 185d165d4acSAndrew Moore 186d165d4acSAndrew Moore /* unset_active_nodes: remove a range of lines from the global-active list */ 187d165d4acSAndrew Moore void 188d165d4acSAndrew Moore unset_active_nodes(np, mp) 189d165d4acSAndrew Moore line_t *np, *mp; 190d165d4acSAndrew Moore { 191d165d4acSAndrew Moore line_t *lp; 192d165d4acSAndrew Moore long i; 193d165d4acSAndrew Moore 194d165d4acSAndrew Moore for (lp = np; lp != mp; lp = lp->q_forw) 195d165d4acSAndrew Moore for (i = 0; i < active_last; i++) 196d165d4acSAndrew Moore if (active_list[active_ndx] == lp) { 197d165d4acSAndrew Moore active_list[active_ndx] = NULL; 198d165d4acSAndrew Moore active_ndx = INC_MOD(active_ndx, active_last - 1); 199d165d4acSAndrew Moore break; 200d165d4acSAndrew Moore } else active_ndx = INC_MOD(active_ndx, active_last - 1); 201d165d4acSAndrew Moore } 202d165d4acSAndrew Moore 203d165d4acSAndrew Moore 204d165d4acSAndrew Moore /* next_active_node: return the next global-active line node */ 205d165d4acSAndrew Moore line_t * 206d165d4acSAndrew Moore next_active_node() 207d165d4acSAndrew Moore { 208d165d4acSAndrew Moore while (active_ptr < active_last && active_list[active_ptr] == NULL) 209d165d4acSAndrew Moore active_ptr++; 210d165d4acSAndrew Moore return (active_ptr < active_last) ? active_list[active_ptr++] : NULL; 211d165d4acSAndrew Moore } 212d165d4acSAndrew Moore 213d165d4acSAndrew Moore 214d165d4acSAndrew Moore /* clear_active_list: clear the global-active list */ 215d165d4acSAndrew Moore void 216d165d4acSAndrew Moore clear_active_list() 217d165d4acSAndrew Moore { 218d165d4acSAndrew Moore SPL1(); 219d165d4acSAndrew Moore active_size = active_last = active_ptr = active_ndx = 0; 220d165d4acSAndrew Moore free(active_list); 221d165d4acSAndrew Moore active_list = NULL; 222d165d4acSAndrew Moore SPL0(); 223d165d4acSAndrew Moore } 224