4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 /* Copyright (c) 1981 Regents of the University of California */
33 #pragma ident "%Z%%M% %I% %E% SMI"
38 * Routines for address parsing and assignment and checking of address bounds
39 * in command mode. The routine address is called from ex_cmds.c
40 * to parse each component of a command (terminated by , ; or the beginning
41 * of the command itself. It is also called by the scanning routine
42 * in ex_voperate.c from within open/visual.
44 * Other routines here manipulate the externals addr1 and addr2.
45 * These are the first and last lines for the current command.
47 * The variable bigmove remembers whether a non-local glitch of . was
48 * involved in an address expression, so we can set the previous context
49 * mark '' when such a motion occurs.
55 * Set up addr1 and addr2 for commands whose default address is dot.
67 * Call setdot1 to set up default addresses without ever
68 * setting the previous context mark.
78 error(value(vi_TERSE
) ?
79 gettext("Addr1 > addr2") :
80 gettext("First address exceeds second"));
85 * Ex allows you to say
87 * to delete 5 lines, etc.
88 * Such nonsense is implemented by setcount.
96 if (!isdigit(peekchar())) {
104 error(value(vi_TERSE
) ?
105 gettext("Bad count") :
106 gettext("Nonzero count required"));
115 * setcount2(): a version of setcount() which sets addr2 based on addr1 + cnt.
117 * this routine is responsible for setting addr1 (possibly) and addr2
118 * (always); using the [count] to compute addr2.
120 * this is similar setcount(), but it differs in that setcount() sets
121 * addr1 based upon addr2; here we set addr2 based upon addr1 and the
124 * the reason for this is because some commands, of the form:
125 * [range] command [count]
126 * will use [count] to modify the range. E.g.:
127 * change, delete, join, list, yank.
135 if (!isdigit(peekchar())) {
142 error(value(vi_TERSE
) ?
143 gettext("Bad count") :
144 gettext("Nonzero count required"));
145 addr2
= addr1
+ (cnt
- 1);
149 addr1
= addr2
= zero
;
157 * Parse a number out of the command input stream.
165 for (cnt
= 0; isdigit(peekcd());)
166 cnt
= cnt
* 10 + getchar() - '0';
171 * Set the default addresses for commands which use the whole
172 * buffer as default, notably write.
187 * Don't want to set previous context mark so use setdot1().
193 * No address allowed on, e.g. the file command.
200 error(value(vi_TERSE
) ?
201 gettext("No address allowed") :
202 gettext("No address allowed on this command"));
207 * Just about any sequence of address characters is legal.
209 * If you are tricky you can use this routine and the = command
210 * to do simple addition and subtraction of cardinals less
211 * than the number of lines in the file.
215 unsigned char *inputline
;
226 if (isdigit(peekcd())) {
241 switch (c
= getcd()) {
251 error(gettext("Badly formed address"));
261 while (peekchar() == ':')
280 c
= vi_compile(c
, 1);
284 if (inputline
&& execute(0, dot
)) {
286 while (loc1
<= (char *)inputline
) {
293 } else if (loc1
< (char *)inputline
) {
298 last
= (unsigned char *)loc1
;
303 } while (loc1
< (char *)inputline
);
313 if (value(vi_WRAPSCAN
) == 0)
314 error(value(vi_TERSE
) ?
315 gettext("No match to BOTTOM") :
316 gettext("Address search hit BOTTOM without matching pattern"));
322 if (value(vi_WRAPSCAN
) == 0)
323 error(value(vi_TERSE
) ?
324 gettext("No match to TOP") :
325 gettext("Address search hit TOP without matching pattern"));
329 if (execute(0, addr
)) {
330 if (inputline
&& c
== '?') {
331 inputline
= &linebuf
[LBSIZE
];
337 error(value(vi_TERSE
) ?
339 gettext("Pattern not found"));
352 c
= markreg(getchar());
354 error(gettext("Marks are ' and a-z"));
357 error(value(vi_TERSE
) ?
358 gettext("Undefined mark") :
359 gettext("Undefined mark referenced"));
378 error(value(vi_TERSE
) ?
379 gettext("Negative address") :
380 gettext("Negative address - "
381 "first buffer line is 1"));
383 error(value(vi_TERSE
) ?
384 gettext("Not that many lines") :
385 gettext("Not that many lines in buffer"));
392 * Abbreviations to make code smaller
393 * Left over from squashing ex version 1.1 into
394 * 11/34's and 11/40's.