1 /* $NetBSD: ex.c,v 1.2 2013/11/22 15:52:05 christos Exp $ */ 2 /*- 3 * Copyright (c) 1992, 1993, 1994 4 * The Regents of the University of California. All rights reserved. 5 * Copyright (c) 1992, 1993, 1994, 1995, 1996 6 * Keith Bostic. All rights reserved. 7 * 8 * See the LICENSE file for redistribution information. 9 */ 10 11 #include "config.h" 12 13 #ifndef lint 14 static const char sccsid[] = "Id: ex.c,v 10.75 2004/03/16 14:13:35 skimo Exp (Berkeley) Date: 2004/03/16 14:13:35 "; 15 #endif /* not lint */ 16 17 #include <sys/types.h> 18 #include <sys/queue.h> 19 #include <sys/stat.h> 20 #include <sys/time.h> 21 22 #include <bitstring.h> 23 #include <ctype.h> 24 #include <errno.h> 25 #include <fcntl.h> 26 #include <limits.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <unistd.h> 31 32 #include "../common/common.h" 33 #include "../common/multibyte.h" 34 #include "../vi/vi.h" 35 36 #if defined(DEBUG) && defined(COMLOG) 37 static void ex_comlog __P((SCR *, EXCMD *)); 38 #endif 39 static EXCMDLIST const * 40 ex_comm_search __P((SCR *, CHAR_T *, size_t)); 41 static int ex_discard __P((SCR *)); 42 static int ex_line __P((SCR *, EXCMD *, MARK *, int *, int *)); 43 static int ex_load __P((SCR *)); 44 static void ex_unknown __P((SCR *, CHAR_T *, size_t)); 45 46 /* 47 * ex -- 48 * Main ex loop. 49 * 50 * PUBLIC: int ex __P((SCR **)); 51 */ 52 int 53 ex(SCR **spp) 54 { 55 GS *gp; 56 WIN *wp; 57 MSGS *mp; 58 SCR *sp; 59 TEXT *tp; 60 u_int32_t flags; 61 62 sp = *spp; 63 wp = sp->wp; 64 gp = sp->gp; 65 66 /* Start the ex screen. */ 67 if (ex_init(sp)) 68 return (1); 69 70 /* Flush any saved messages. */ 71 while ((mp = gp->msgq.lh_first) != NULL) { 72 wp->scr_msg(sp, mp->mtype, mp->buf, mp->len); 73 LIST_REMOVE(mp, q); 74 free(mp->buf); 75 free(mp); 76 } 77 78 /* If reading from a file, errors should have name and line info. */ 79 if (F_ISSET(gp, G_SCRIPTED)) { 80 wp->excmd.if_lno = 1; 81 wp->excmd.if_name = strdup("script"); 82 } 83 84 /* 85 * !!! 86 * Initialize the text flags. The beautify edit option historically 87 * applied to ex command input read from a file. In addition, the 88 * first time a ^H was discarded from the input, there was a message, 89 * "^H discarded", that was displayed. We don't bother. 90 */ 91 LF_INIT(TXT_BACKSLASH | TXT_CNTRLD | TXT_CR); 92 for (;; ++wp->excmd.if_lno) { 93 /* Display status line and flush. */ 94 if (F_ISSET(sp, SC_STATUS)) { 95 if (!F_ISSET(sp, SC_EX_SILENT)) 96 msgq_status(sp, sp->lno, 0); 97 F_CLR(sp, SC_STATUS); 98 } 99 (void)ex_fflush(sp); 100 101 /* Set the flags the user can reset. */ 102 if (O_ISSET(sp, O_BEAUTIFY)) 103 LF_SET(TXT_BEAUTIFY); 104 if (O_ISSET(sp, O_PROMPT)) 105 LF_SET(TXT_PROMPT); 106 107 /* Clear any current interrupts, and get a command. */ 108 CLR_INTERRUPT(sp); 109 if (ex_txt(sp, &sp->tiq, ':', flags)) 110 return (1); 111 if (INTERRUPTED(sp)) { 112 (void)ex_puts(sp, "\n"); 113 (void)ex_fflush(sp); 114 continue; 115 } 116 117 /* Initialize the command structure. */ 118 CLEAR_EX_PARSER(&wp->excmd); 119 120 /* 121 * If the user entered a single carriage return, send 122 * ex_cmd() a separator -- it discards single newlines. 123 */ 124 tp = sp->tiq.cqh_first; 125 if (tp->len == 0) { 126 static CHAR_T space = ' '; 127 wp->excmd.cp = &space; /* __TK__ why not |? */ 128 wp->excmd.clen = 1; 129 } else { 130 wp->excmd.cp = tp->lb; 131 wp->excmd.clen = tp->len; 132 } 133 F_INIT(&wp->excmd, E_NRSEP); 134 135 if (ex_cmd(sp) && F_ISSET(gp, G_SCRIPTED)) 136 return (1); 137 138 if (INTERRUPTED(sp)) { 139 CLR_INTERRUPT(sp); 140 msgq(sp, M_ERR, "170|Interrupted"); 141 } 142 143 /* 144 * If the last command caused a restart, or switched screens 145 * or into vi, return. 146 */ 147 if (F_ISSET(gp, G_SRESTART) || F_ISSET(sp, SC_SSWITCH | SC_VI)) { 148 *spp = sp; 149 break; 150 } 151 152 /* If the last command switched files, we don't care. */ 153 F_CLR(sp, SC_FSWITCH); 154 155 /* 156 * If we're exiting this screen, move to the next one. By 157 * definition, this means returning into vi, so return to the 158 * main editor loop. The ordering is careful, don't discard 159 * the contents of sp until the end. 160 */ 161 if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) { 162 if (file_end(sp, NULL, F_ISSET(sp, SC_EXIT_FORCE))) 163 return (1); 164 *spp = screen_next(sp); 165 return (screen_end(sp)); 166 } 167 } 168 return (0); 169 } 170 171 /* 172 * ex_cmd -- 173 * The guts of the ex parser: parse and execute a string containing 174 * ex commands. 175 * 176 * !!! 177 * This code MODIFIES the string that gets passed in, to delete quoting 178 * characters, etc. The string cannot be readonly/text space, nor should 179 * you expect to use it again after ex_cmd() returns. 180 * 181 * !!! 182 * For the fun of it, if you want to see if a vi clone got the ex argument 183 * parsing right, try: 184 * 185 * echo 'foo|bar' > file1; echo 'foo/bar' > file2; 186 * vi 187 * :edit +1|s/|/PIPE/|w file1| e file2|1 | s/\//SLASH/|wq 188 * 189 * or: vi 190 * :set|file|append|set|file 191 * 192 * For extra credit, try them in a startup .exrc file. 193 * 194 * PUBLIC: int ex_cmd __P((SCR *)); 195 */ 196 int 197 ex_cmd(SCR *sp) 198 { 199 enum nresult nret; 200 EX_PRIVATE *exp; 201 EXCMD *ecp; 202 GS *gp; 203 WIN *wp; 204 MARK cur; 205 db_recno_t lno; 206 size_t arg1_len, discard, len; 207 u_int32_t flags; 208 long ltmp; 209 int at_found, gv_found; 210 int cnt, delim, isaddr, namelen; 211 int newscreen, notempty, tmp, vi_address; 212 CHAR_T *arg1, *s, *p, *t; 213 ARG_CHAR_T ch; 214 const CHAR_T *n; 215 const char *np; 216 217 gp = sp->gp; 218 wp = sp->wp; 219 exp = EXP(sp); 220 ch = '\0'; /* XXX: gcc -O1 -Wuninitialized */ 221 222 /* 223 * We always start running the command on the top of the stack. 224 * This means that *everything* must be resolved when we leave 225 * this function for any reason. 226 */ 227 loop: ecp = wp->ecq.lh_first; 228 229 /* If we're reading a command from a file, set up error information. */ 230 if (ecp->if_name != NULL) { 231 wp->if_lno = ecp->if_lno; 232 wp->if_name = ecp->if_name; 233 } 234 235 /* 236 * If a move to the end of the file is scheduled for this command, 237 * do it now. 238 */ 239 if (F_ISSET(ecp, E_MOVETOEND)) { 240 if (db_last(sp, &sp->lno)) 241 goto rfail; 242 sp->cno = 0; 243 F_CLR(ecp, E_MOVETOEND); 244 } 245 246 /* If we found a newline, increment the count now. */ 247 if (F_ISSET(ecp, E_NEWLINE)) { 248 ++wp->if_lno; 249 ++ecp->if_lno; 250 F_CLR(ecp, E_NEWLINE); 251 } 252 253 /* (Re)initialize the EXCMD structure, preserving some flags. */ 254 CLEAR_EX_CMD(ecp); 255 256 /* Initialize the argument structures. */ 257 if (argv_init(sp, ecp)) 258 goto err; 259 260 /* Initialize +cmd, saved command information. */ 261 arg1 = NULL; 262 ecp->save_cmdlen = 0; 263 264 /* Skip <blank>s, empty lines. */ 265 for (notempty = 0; ecp->clen > 0; ++ecp->cp, --ecp->clen) 266 if ((ch = (UCHAR_T)*ecp->cp) == '\n') { 267 ++wp->if_lno; 268 ++ecp->if_lno; 269 } else if (ISBLANK(ch)) 270 notempty = 1; 271 else 272 break; 273 274 /* 275 * !!! 276 * Permit extra colons at the start of the line. Historically, 277 * ex/vi allowed a single extra one. It's simpler not to count. 278 * The stripping is done here because, historically, any command 279 * could have preceding colons, e.g. ":g/pattern/:p" worked. 280 */ 281 if (ecp->clen != 0 && ch == ':') { 282 notempty = 1; 283 while (--ecp->clen > 0 && (ch = (UCHAR_T)*++ecp->cp) == ':'); 284 } 285 286 /* 287 * Command lines that start with a double-quote are comments. 288 * 289 * !!! 290 * Historically, there was no escape or delimiter for a comment, e.g. 291 * :"foo|set was a single comment and nothing was output. Since nvi 292 * permits users to escape <newline> characters into command lines, we 293 * have to check for that case. 294 */ 295 if (ecp->clen != 0 && ch == '"') { 296 while (--ecp->clen > 0 && *++ecp->cp != '\n'); 297 if (*ecp->cp == '\n') { 298 F_SET(ecp, E_NEWLINE); 299 ++ecp->cp; 300 --ecp->clen; 301 } 302 goto loop; 303 } 304 305 /* Skip whitespace. */ 306 for (; ecp->clen > 0; ++ecp->cp, --ecp->clen) { 307 ch = (UCHAR_T)*ecp->cp; 308 if (!ISBLANK(ch)) 309 break; 310 } 311 312 /* 313 * The last point at which an empty line can mean do nothing. 314 * 315 * !!! 316 * Historically, in ex mode, lines containing only <blank> characters 317 * were the same as a single <carriage-return>, i.e. a default command. 318 * In vi mode, they were ignored. In .exrc files this was a serious 319 * annoyance, as vi kept trying to treat them as print commands. We 320 * ignore backward compatibility in this case, discarding lines that 321 * contain only <blank> characters from .exrc files. 322 * 323 * !!! 324 * This is where you end up when you're done a command, i.e. clen has 325 * gone to zero. Continue if there are more commands to run. 326 */ 327 if (ecp->clen == 0 && 328 (!notempty || F_ISSET(sp, SC_VI) || F_ISSET(ecp, E_BLIGNORE))) { 329 if (ex_load(sp)) 330 goto rfail; 331 ecp = wp->ecq.lh_first; 332 if (ecp->clen == 0) 333 goto rsuccess; 334 goto loop; 335 } 336 337 /* 338 * Check to see if this is a command for which we may want to move 339 * the cursor back up to the previous line. (The command :1<CR> 340 * wants a <newline> separator, but the command :<CR> wants to erase 341 * the command line.) If the line is empty except for <blank>s, 342 * <carriage-return> or <eof>, we'll probably want to move up. I 343 * don't think there's any way to get <blank> characters *after* the 344 * command character, but this is the ex parser, and I've been wrong 345 * before. 346 */ 347 if (F_ISSET(ecp, E_NRSEP) && 348 ecp->clen != 0 && (ecp->clen != 1 || ecp->cp[0] != '\004')) 349 F_CLR(ecp, E_NRSEP); 350 351 /* Parse command addresses. */ 352 if (ex_range(sp, ecp, &tmp)) 353 goto rfail; 354 if (tmp) 355 goto err; 356 357 /* 358 * Skip <blank>s and any more colons (the command :3,5:print 359 * worked, historically). 360 */ 361 for (; ecp->clen > 0; ++ecp->cp, --ecp->clen) { 362 ch = (UCHAR_T)*ecp->cp; 363 if (!ISBLANK(ch) && ch != ':') 364 break; 365 } 366 367 /* 368 * If no command, ex does the last specified of p, l, or #, and vi 369 * moves to the line. Otherwise, determine the length of the command 370 * name by looking for the first non-alphabetic character. (There 371 * are a few non-alphabetic characters in command names, but they're 372 * all single character commands.) This isn't a great test, because 373 * it means that, for the command ":e +cut.c file", we'll report that 374 * the command "cut" wasn't known. However, it makes ":e+35 file" work 375 * correctly. 376 * 377 * !!! 378 * Historically, lines with multiple adjacent (or <blank> separated) 379 * command separators were very strange. For example, the command 380 * |||<carriage-return>, when the cursor was on line 1, displayed 381 * lines 2, 3 and 5 of the file. In addition, the command " | " 382 * would only display the line after the next line, instead of the 383 * next two lines. No ideas why. It worked reasonably when executed 384 * from vi mode, and displayed lines 2, 3, and 4, so we do a default 385 * command for each separator. 386 */ 387 #define SINGLE_CHAR_COMMANDS "\004!#&*<=>@~" 388 newscreen = 0; 389 if (ecp->clen != 0 && ecp->cp[0] != '|' && ecp->cp[0] != '\n') { 390 if (strchr(SINGLE_CHAR_COMMANDS, *ecp->cp)) { 391 p = ecp->cp; 392 ++ecp->cp; 393 --ecp->clen; 394 namelen = 1; 395 } else { 396 for (p = ecp->cp; 397 ecp->clen > 0; --ecp->clen, ++ecp->cp) 398 if (!ISALPHA((UCHAR_T)*ecp->cp)) 399 break; 400 if ((namelen = ecp->cp - p) == 0) { 401 msgq(sp, M_ERR, "080|Unknown command name"); 402 goto err; 403 } 404 } 405 406 /* 407 * !!! 408 * Historic vi permitted flags to immediately follow any 409 * subset of the 'delete' command, but then did not permit 410 * further arguments (flag, buffer, count). Make it work. 411 * Permit further arguments for the few shreds of dignity 412 * it offers. 413 * 414 * Adding commands that start with 'd', and match "delete" 415 * up to a l, p, +, - or # character can break this code. 416 * 417 * !!! 418 * Capital letters beginning the command names ex, edit, 419 * next, previous, tag and visual (in vi mode) indicate the 420 * command should happen in a new screen. 421 */ 422 switch (p[0]) { 423 case 'd': 424 for (s = p, 425 n = cmds[C_DELETE].name; *s == *n; ++s, ++n); 426 if (s[0] == 'l' || s[0] == 'p' || s[0] == '+' || 427 s[0] == '-' || s[0] == '^' || s[0] == '#') { 428 len = (ecp->cp - p) - (s - p); 429 ecp->cp -= len; 430 ecp->clen += len; 431 ecp->rcmd = cmds[C_DELETE]; 432 ecp->rcmd.syntax = "1bca1"; 433 ecp->cmd = &ecp->rcmd; 434 goto skip_srch; 435 } 436 break; 437 case 'E': case 'F': case 'N': case 'P': case 'T': case 'V': 438 newscreen = 1; 439 p[0] = TOLOWER(p[0]); 440 break; 441 } 442 443 /* 444 * Search the table for the command. 445 * 446 * !!! 447 * Historic vi permitted the mark to immediately follow the 448 * 'k' in the 'k' command. Make it work. 449 * 450 * !!! 451 * Historic vi permitted any flag to follow the s command, e.g. 452 * "s/e/E/|s|sgc3p" was legal. Make the command "sgc" work. 453 * Since the following characters all have to be flags, i.e. 454 * alphabetics, we can let the s command routine return errors 455 * if it was some illegal command string. This code will break 456 * if an "sg" or similar command is ever added. The substitute 457 * code doesn't care if it's a "cgr" flag or a "#lp" flag that 458 * follows the 's', but we limit the choices here to "cgr" so 459 * that we get unknown command messages for wrong combinations. 460 */ 461 if ((ecp->cmd = ex_comm_search(sp, p, namelen)) == NULL) 462 switch (p[0]) { 463 case 'k': 464 if (namelen == 2) { 465 ecp->cp -= namelen - 1; 466 ecp->clen += namelen - 1; 467 ecp->cmd = &cmds[C_K]; 468 break; 469 } 470 goto unknown; 471 case 's': 472 for (s = p + 1, cnt = namelen; --cnt; ++s) 473 if (s[0] != 'c' && 474 s[0] != 'g' && s[0] != 'r') 475 break; 476 if (cnt == 0) { 477 ecp->cp -= namelen - 1; 478 ecp->clen += namelen - 1; 479 ecp->rcmd = cmds[C_SUBSTITUTE]; 480 ecp->rcmd.fn = ex_subagain; 481 ecp->cmd = &ecp->rcmd; 482 break; 483 } 484 /* FALLTHROUGH */ 485 default: 486 unknown: if (newscreen) 487 p[0] = TOUPPER((UCHAR_T)p[0]); 488 ex_unknown(sp, p, namelen); 489 goto err; 490 } 491 492 /* 493 * The visual command has a different syntax when called 494 * from ex than when called from a vi colon command. FMH. 495 * Make the change now, before we test for the newscreen 496 * semantic, so that we're testing the right one. 497 */ 498 skip_srch: if (ecp->cmd == &cmds[C_VISUAL_EX] && F_ISSET(sp, SC_VI)) 499 ecp->cmd = &cmds[C_VISUAL_VI]; 500 501 /* 502 * !!! 503 * Historic vi permitted a capital 'P' at the beginning of 504 * any command that started with 'p'. Probably wanted the 505 * P[rint] command for backward compatibility, and the code 506 * just made Preserve and Put work by accident. Nvi uses 507 * Previous to mean previous-in-a-new-screen, so be careful. 508 */ 509 if (newscreen && !F_ISSET(ecp->cmd, E_NEWSCREEN) && 510 (ecp->cmd == &cmds[C_PRINT] || 511 ecp->cmd == &cmds[C_PRESERVE])) 512 newscreen = 0; 513 514 /* Test for a newscreen associated with this command. */ 515 if (newscreen && !F_ISSET(ecp->cmd, E_NEWSCREEN)) 516 goto unknown; 517 518 /* Secure means no shell access. */ 519 if (F_ISSET(ecp->cmd, E_SECURE) && O_ISSET(sp, O_SECURE)) { 520 ex_wemsg(sp, ecp->cmd->name, EXM_SECURE); 521 goto err; 522 } 523 524 /* 525 * Multiple < and > characters; another "feature". Note, 526 * The string passed to the underlying function may not be 527 * nul terminated in this case. 528 */ 529 if ((ecp->cmd == &cmds[C_SHIFTL] && *p == '<') || 530 (ecp->cmd == &cmds[C_SHIFTR] && *p == '>')) { 531 for (ch = (UCHAR_T)*p; 532 ecp->clen > 0; --ecp->clen, ++ecp->cp) 533 if (*ecp->cp != ch) 534 break; 535 if (argv_exp0(sp, ecp, p, ecp->cp - p)) 536 goto err; 537 } 538 539 /* Set the format style flags for the next command. */ 540 if (ecp->cmd == &cmds[C_HASH]) 541 exp->fdef = E_C_HASH; 542 else if (ecp->cmd == &cmds[C_LIST]) 543 exp->fdef = E_C_LIST; 544 else if (ecp->cmd == &cmds[C_PRINT]) 545 exp->fdef = E_C_PRINT; 546 F_CLR(ecp, E_USELASTCMD); 547 } else { 548 /* Print is the default command. */ 549 ecp->cmd = &cmds[C_PRINT]; 550 551 /* Set the saved format flags. */ 552 F_SET(ecp, exp->fdef); 553 554 /* 555 * !!! 556 * If no address was specified, and it's not a global command, 557 * we up the address by one. (I have no idea why globals are 558 * exempted, but it's (ahem) historic practice.) 559 */ 560 if (ecp->addrcnt == 0 && !F_ISSET(sp, SC_EX_GLOBAL)) { 561 ecp->addrcnt = 1; 562 ecp->addr1.lno = sp->lno + 1; 563 ecp->addr1.cno = sp->cno; 564 } 565 566 F_SET(ecp, E_USELASTCMD); 567 } 568 569 /* 570 * !!! 571 * Historically, the number option applied to both ex and vi. One 572 * strangeness was that ex didn't switch display formats until a 573 * command was entered, e.g. <CR>'s after the set didn't change to 574 * the new format, but :1p would. 575 */ 576 if (O_ISSET(sp, O_NUMBER)) { 577 F_SET(ecp, E_OPTNUM); 578 FL_SET(ecp->iflags, E_C_HASH); 579 } else 580 F_CLR(ecp, E_OPTNUM); 581 582 /* Check for ex mode legality. */ 583 if (F_ISSET(sp, SC_EX) && (F_ISSET(ecp->cmd, E_VIONLY) || newscreen)) { 584 msgq_wstr(sp, M_ERR, ecp->cmd->name, 585 "082|%s: command not available in ex mode"); 586 goto err; 587 } 588 589 /* Add standard command flags. */ 590 F_SET(ecp, ecp->cmd->flags); 591 if (!newscreen) 592 F_CLR(ecp, E_NEWSCREEN); 593 594 /* 595 * There are three normal termination cases for an ex command. They 596 * are the end of the string (ecp->clen), or unescaped (by <literal 597 * next> characters) <newline> or '|' characters. As we're now past 598 * possible addresses, we can determine how long the command is, so we 599 * don't have to look for all the possible terminations. Naturally, 600 * there are some exciting special cases: 601 * 602 * 1: The bang, global, v and the filter versions of the read and 603 * write commands are delimited by <newline>s (they can contain 604 * shell pipes). 605 * 2: The ex, edit, next and visual in vi mode commands all take ex 606 * commands as their first arguments. 607 * 3: The s command takes an RE as its first argument, and wants it 608 * to be specially delimited. 609 * 610 * Historically, '|' characters in the first argument of the ex, edit, 611 * next, vi visual, and s commands didn't delimit the command. And, 612 * in the filter cases for read and write, and the bang, global and v 613 * commands, they did not delimit the command at all. 614 * 615 * For example, the following commands were legal: 616 * 617 * :edit +25|s/abc/ABC/ file.c 618 * :s/|/PIPE/ 619 * :read !spell % | columnate 620 * :global/pattern/p|l 621 * 622 * It's not quite as simple as it sounds, however. The command: 623 * 624 * :s/a/b/|s/c/d|set 625 * 626 * was also legal, i.e. the historic ex parser (using the word loosely, 627 * since "parser" implies some regularity of syntax) delimited the RE's 628 * based on its delimiter and not anything so irretrievably vulgar as a 629 * command syntax. 630 * 631 * Anyhow, the following code makes this all work. First, for the 632 * special cases we move past their special argument(s). Then, we 633 * do normal command processing on whatever is left. Barf-O-Rama. 634 */ 635 discard = 0; /* Characters discarded from the command. */ 636 arg1_len = 0; 637 ecp->save_cmd = ecp->cp; 638 if (ecp->cmd == &cmds[C_EDIT] || ecp->cmd == &cmds[C_EX] || 639 ecp->cmd == &cmds[C_NEXT] || ecp->cmd == &cmds[C_VISUAL_VI] || 640 ecp->cmd == &cmds[C_VSPLIT]) { 641 /* 642 * Move to the next non-whitespace character. A '!' 643 * immediately following the command is eaten as a 644 * force flag. 645 */ 646 if (ecp->clen > 0 && *ecp->cp == '!') { 647 ++ecp->cp; 648 --ecp->clen; 649 FL_SET(ecp->iflags, E_C_FORCE); 650 651 /* Reset, don't reparse. */ 652 ecp->save_cmd = ecp->cp; 653 } 654 for (; ecp->clen > 0; --ecp->clen, ++ecp->cp) 655 if (!ISBLANK(*ecp->cp)) 656 break; 657 /* 658 * QUOTING NOTE: 659 * 660 * The historic implementation ignored all escape characters 661 * so there was no way to put a space or newline into the +cmd 662 * field. We do a simplistic job of fixing it by moving to the 663 * first whitespace character that isn't escaped. The escaping 664 * characters are stripped as no longer useful. 665 */ 666 if (ecp->clen > 0 && *ecp->cp == '+') { 667 ++ecp->cp; 668 --ecp->clen; 669 for (arg1 = p = ecp->cp; 670 ecp->clen > 0; --ecp->clen, ++ecp->cp) { 671 ch = (UCHAR_T)*ecp->cp; 672 if (IS_ESCAPE(sp, ecp, ch) && 673 ecp->clen > 1) { 674 ++discard; 675 --ecp->clen; 676 ch = (UCHAR_T)*++ecp->cp; 677 } else if (ISBLANK(ch)) 678 break; 679 *p++ = ch; 680 } 681 arg1_len = ecp->cp - arg1; 682 683 /* Reset, so the first argument isn't reparsed. */ 684 ecp->save_cmd = ecp->cp; 685 } 686 } else if (ecp->cmd == &cmds[C_BANG] || 687 ecp->cmd == &cmds[C_GLOBAL] || ecp->cmd == &cmds[C_V]) { 688 /* 689 * QUOTING NOTE: 690 * 691 * We use backslashes to escape <newline> characters, although 692 * this wasn't historic practice for the bang command. It was 693 * for the global and v commands, and it's common usage when 694 * doing text insert during the command. Escaping characters 695 * are stripped as no longer useful. 696 */ 697 for (p = ecp->cp; ecp->clen > 0; --ecp->clen, ++ecp->cp) { 698 ch = (UCHAR_T)*ecp->cp; 699 if (ch == '\\' && ecp->clen > 1 && ecp->cp[1] == '\n') { 700 ++discard; 701 --ecp->clen; 702 ch = (UCHAR_T)*++ecp->cp; 703 704 ++wp->if_lno; 705 ++ecp->if_lno; 706 } else if (ch == '\n') 707 break; 708 *p++ = ch; 709 } 710 } else if (ecp->cmd == &cmds[C_READ] || ecp->cmd == &cmds[C_WRITE]) { 711 /* 712 * For write commands, if the next character is a <blank>, and 713 * the next non-blank character is a '!', it's a filter command 714 * and we want to eat everything up to the <newline>. For read 715 * commands, if the next non-blank character is a '!', it's a 716 * filter command and we want to eat everything up to the next 717 * <newline>. Otherwise, we're done. 718 */ 719 for (tmp = 0; ecp->clen > 0; --ecp->clen, ++ecp->cp) { 720 ch = (UCHAR_T)*ecp->cp; 721 if (ISBLANK(ch)) 722 tmp = 1; 723 else 724 break; 725 } 726 if (ecp->clen > 0 && ch == '!' && 727 (ecp->cmd == &cmds[C_READ] || tmp)) 728 for (; ecp->clen > 0; --ecp->clen, ++ecp->cp) 729 if (ecp->cp[0] == '\n') 730 break; 731 } else if (ecp->cmd == &cmds[C_SUBSTITUTE]) { 732 /* 733 * Move to the next non-whitespace character, we'll use it as 734 * the delimiter. If the character isn't an alphanumeric or 735 * a '|', it's the delimiter, so parse it. Otherwise, we're 736 * into something like ":s g", so use the special s command. 737 */ 738 for (; ecp->clen > 0; --ecp->clen, ++ecp->cp) 739 if (!ISBLANK(ecp->cp[0])) 740 break; 741 742 if (ISALNUM((UCHAR_T)ecp->cp[0]) || ecp->cp[0] == '|') { 743 ecp->rcmd = cmds[C_SUBSTITUTE]; 744 ecp->rcmd.fn = ex_subagain; 745 ecp->cmd = &ecp->rcmd; 746 } else if (ecp->clen > 0) { 747 /* 748 * QUOTING NOTE: 749 * 750 * Backslashes quote delimiter characters for RE's. 751 * The backslashes are NOT removed since they'll be 752 * used by the RE code. Move to the third delimiter 753 * that's not escaped (or the end of the command). 754 */ 755 delim = *ecp->cp; 756 ++ecp->cp; 757 --ecp->clen; 758 for (cnt = 2; ecp->clen > 0 && 759 cnt != 0; --ecp->clen, ++ecp->cp) 760 if (ecp->cp[0] == '\\' && 761 ecp->clen > 1) { 762 ++ecp->cp; 763 --ecp->clen; 764 } else if (ecp->cp[0] == delim) 765 --cnt; 766 } 767 } 768 769 /* 770 * Use normal quoting and termination rules to find the end of this 771 * command. 772 * 773 * QUOTING NOTE: 774 * 775 * Historically, vi permitted ^V's to escape <newline>'s in the .exrc 776 * file. It was almost certainly a bug, but that's what bug-for-bug 777 * compatibility means, Grasshopper. Also, ^V's escape the command 778 * delimiters. Literal next quote characters in front of the newlines, 779 * '|' characters or literal next characters are stripped as they're 780 * no longer useful. 781 */ 782 vi_address = ecp->clen != 0 && ecp->cp[0] != '\n'; 783 for (p = ecp->cp; ecp->clen > 0; --ecp->clen, ++ecp->cp) { 784 ch = (UCHAR_T)ecp->cp[0]; 785 if (IS_ESCAPE(sp, ecp, ch) && ecp->clen > 1) { 786 ARG_CHAR_T tmp1 = (UCHAR_T)ecp->cp[1]; 787 if (tmp1 == '\n' || tmp1 == '|') { 788 if (tmp1 == '\n') { 789 ++wp->if_lno; 790 ++ecp->if_lno; 791 } 792 ++discard; 793 --ecp->clen; 794 ++ecp->cp; 795 ch = tmp1; 796 } 797 } else if (ch == '\n' || ch == '|') { 798 if (ch == '\n') 799 F_SET(ecp, E_NEWLINE); 800 --ecp->clen; 801 break; 802 } 803 *p++ = ch; 804 } 805 806 /* 807 * Save off the next command information, go back to the 808 * original start of the command. 809 */ 810 p = ecp->cp + 1; 811 ecp->cp = ecp->save_cmd; 812 ecp->save_cmd = p; 813 ecp->save_cmdlen = ecp->clen; 814 ecp->clen = ((ecp->save_cmd - ecp->cp) - 1) - discard; 815 816 /* 817 * QUOTING NOTE: 818 * 819 * The "set tags" command historically used a backslash, not the 820 * user's literal next character, to escape whitespace. Handle 821 * it here instead of complicating the argv_exp3() code. Note, 822 * this isn't a particularly complex trap, and if backslashes were 823 * legal in set commands, this would have to be much more complicated. 824 */ 825 if (ecp->cmd == &cmds[C_SET]) 826 for (p = ecp->cp, len = ecp->clen; len > 0; --len, ++p) 827 if (*p == '\\') 828 *p = CH_LITERAL; 829 830 /* 831 * Set the default addresses. It's an error to specify an address for 832 * a command that doesn't take them. If two addresses are specified 833 * for a command that only takes one, lose the first one. Two special 834 * cases here, some commands take 0 or 2 addresses. For most of them 835 * (the E_ADDR2_ALL flag), 0 defaults to the entire file. For one 836 * (the `!' command, the E_ADDR2_NONE flag), 0 defaults to no lines. 837 * 838 * Also, if the file is empty, some commands want to use an address of 839 * 0, i.e. the entire file is 0 to 0, and the default first address is 840 * 0. Otherwise, an entire file is 1 to N and the default line is 1. 841 * Note, we also add the E_ADDR_ZERO flag to the command flags, for the 842 * case where the 0 address is only valid if it's a default address. 843 * 844 * Also, set a flag if we set the default addresses. Some commands 845 * (ex: z) care if the user specified an address or if we just used 846 * the current cursor. 847 */ 848 switch (F_ISSET(ecp, E_ADDR1 | E_ADDR2 | E_ADDR2_ALL | E_ADDR2_NONE)) { 849 case E_ADDR1: /* One address: */ 850 switch (ecp->addrcnt) { 851 case 0: /* Default cursor/empty file. */ 852 ecp->addrcnt = 1; 853 F_SET(ecp, E_ADDR_DEF); 854 if (F_ISSET(ecp, E_ADDR_ZERODEF)) { 855 if (db_last(sp, &lno)) 856 goto err; 857 if (lno == 0) { 858 ecp->addr1.lno = 0; 859 F_SET(ecp, E_ADDR_ZERO); 860 } else 861 ecp->addr1.lno = sp->lno; 862 } else 863 ecp->addr1.lno = sp->lno; 864 ecp->addr1.cno = sp->cno; 865 break; 866 case 1: 867 break; 868 case 2: /* Lose the first address. */ 869 ecp->addrcnt = 1; 870 ecp->addr1 = ecp->addr2; 871 } 872 break; 873 case E_ADDR2_NONE: /* Zero/two addresses: */ 874 if (ecp->addrcnt == 0) /* Default to nothing. */ 875 break; 876 goto two_addr; 877 case E_ADDR2_ALL: /* Zero/two addresses: */ 878 if (ecp->addrcnt == 0) { /* Default entire/empty file. */ 879 F_SET(ecp, E_ADDR_DEF); 880 ecp->addrcnt = 2; 881 if (sp->ep == NULL) 882 ecp->addr2.lno = 0; 883 else if (db_last(sp, &ecp->addr2.lno)) 884 goto err; 885 if (F_ISSET(ecp, E_ADDR_ZERODEF) && 886 ecp->addr2.lno == 0) { 887 ecp->addr1.lno = 0; 888 F_SET(ecp, E_ADDR_ZERO); 889 } else 890 ecp->addr1.lno = 1; 891 ecp->addr1.cno = ecp->addr2.cno = 0; 892 F_SET(ecp, E_ADDR2_ALL); 893 break; 894 } 895 /* FALLTHROUGH */ 896 case E_ADDR2: /* Two addresses: */ 897 two_addr: switch (ecp->addrcnt) { 898 case 0: /* Default cursor/empty file. */ 899 ecp->addrcnt = 2; 900 F_SET(ecp, E_ADDR_DEF); 901 if (sp->lno == 1 && 902 F_ISSET(ecp, E_ADDR_ZERODEF)) { 903 if (db_last(sp, &lno)) 904 goto err; 905 if (lno == 0) { 906 ecp->addr1.lno = ecp->addr2.lno = 0; 907 F_SET(ecp, E_ADDR_ZERO); 908 } else 909 ecp->addr1.lno = 910 ecp->addr2.lno = sp->lno; 911 } else 912 ecp->addr1.lno = ecp->addr2.lno = sp->lno; 913 ecp->addr1.cno = ecp->addr2.cno = sp->cno; 914 break; 915 case 1: /* Default to first address. */ 916 //ecp->addrcnt = 2; /* XXX Was this needed ??? */ 917 ecp->addr2 = ecp->addr1; 918 break; 919 case 2: 920 break; 921 } 922 break; 923 default: 924 if (ecp->addrcnt) /* Error. */ 925 goto usage; 926 } 927 928 /* 929 * !!! 930 * The ^D scroll command historically scrolled the value of the scroll 931 * option or to EOF. It was an error if the cursor was already at EOF. 932 * (Leading addresses were permitted, but were then ignored.) 933 */ 934 if (ecp->cmd == &cmds[C_SCROLL]) { 935 ecp->addrcnt = 2; 936 ecp->addr1.lno = sp->lno + 1; 937 ecp->addr2.lno = sp->lno + O_VAL(sp, O_SCROLL); 938 ecp->addr1.cno = ecp->addr2.cno = sp->cno; 939 if (db_last(sp, &lno)) 940 goto err; 941 if (lno != 0 && lno > sp->lno && ecp->addr2.lno > lno) 942 ecp->addr2.lno = lno; 943 } 944 945 ecp->flagoff = 0; 946 for (np = ecp->cmd->syntax; *np != '\0'; ++np) { 947 /* 948 * The force flag is sensitive to leading whitespace, i.e. 949 * "next !" is different from "next!". Handle it before 950 * skipping leading <blank>s. 951 */ 952 if (*np == '!') { 953 if (ecp->clen > 0 && *ecp->cp == '!') { 954 ++ecp->cp; 955 --ecp->clen; 956 FL_SET(ecp->iflags, E_C_FORCE); 957 } 958 continue; 959 } 960 961 /* Skip leading <blank>s. */ 962 for (; ecp->clen > 0; --ecp->clen, ++ecp->cp) 963 if (!ISBLANK(*ecp->cp)) 964 break; 965 if (ecp->clen == 0) 966 break; 967 968 switch (*np) { 969 case '1': /* +, -, #, l, p */ 970 /* 971 * !!! 972 * Historically, some flags were ignored depending 973 * on where they occurred in the command line. For 974 * example, in the command, ":3+++p--#", historic vi 975 * acted on the '#' flag, but ignored the '-' flags. 976 * It's unambiguous what the flags mean, so we just 977 * handle them regardless of the stupidity of their 978 * location. 979 */ 980 for (; ecp->clen; --ecp->clen, ++ecp->cp) 981 switch (*ecp->cp) { 982 case '+': 983 ++ecp->flagoff; 984 break; 985 case '-': 986 case '^': 987 --ecp->flagoff; 988 break; 989 case '#': 990 F_CLR(ecp, E_OPTNUM); 991 FL_SET(ecp->iflags, E_C_HASH); 992 exp->fdef |= E_C_HASH; 993 break; 994 case 'l': 995 FL_SET(ecp->iflags, E_C_LIST); 996 exp->fdef |= E_C_LIST; 997 break; 998 case 'p': 999 FL_SET(ecp->iflags, E_C_PRINT); 1000 exp->fdef |= E_C_PRINT; 1001 break; 1002 default: 1003 goto end_case1; 1004 } 1005 end_case1: break; 1006 case '2': /* -, ., +, ^ */ 1007 case '3': /* -, ., +, ^, = */ 1008 for (; ecp->clen; --ecp->clen, ++ecp->cp) 1009 switch (*ecp->cp) { 1010 case '-': 1011 FL_SET(ecp->iflags, E_C_DASH); 1012 break; 1013 case '.': 1014 FL_SET(ecp->iflags, E_C_DOT); 1015 break; 1016 case '+': 1017 FL_SET(ecp->iflags, E_C_PLUS); 1018 break; 1019 case '^': 1020 FL_SET(ecp->iflags, E_C_CARAT); 1021 break; 1022 case '=': 1023 if (*np == '3') { 1024 FL_SET(ecp->iflags, E_C_EQUAL); 1025 break; 1026 } 1027 /* FALLTHROUGH */ 1028 default: 1029 goto end_case23; 1030 } 1031 end_case23: break; 1032 case 'b': /* buffer */ 1033 /* 1034 * !!! 1035 * Historically, "d #" was a delete with a flag, not a 1036 * delete into the '#' buffer. If the current command 1037 * permits a flag, don't use one as a buffer. However, 1038 * the 'l' and 'p' flags were legal buffer names in the 1039 * historic ex, and were used as buffers, not flags. 1040 */ 1041 if ((ecp->cp[0] == '+' || ecp->cp[0] == '-' || 1042 ecp->cp[0] == '^' || ecp->cp[0] == '#') && 1043 strchr(np, '1') != NULL) 1044 break; 1045 /* 1046 * !!! 1047 * Digits can't be buffer names in ex commands, or the 1048 * command "d2" would be a delete into buffer '2', and 1049 * not a two-line deletion. 1050 */ 1051 if (!ISDIGIT((UCHAR_T)ecp->cp[0])) { 1052 ecp->buffer = (UCHAR_T)*ecp->cp; 1053 ++ecp->cp; 1054 --ecp->clen; 1055 FL_SET(ecp->iflags, E_C_BUFFER); 1056 } 1057 break; 1058 case 'c': /* count [01+a] */ 1059 ++np; 1060 /* Validate any signed value. */ 1061 if (!ISDIGIT((UCHAR_T)*ecp->cp) && (*np != '+' || 1062 (*ecp->cp != '+' && *ecp->cp != '-'))) 1063 break; 1064 /* If a signed value, set appropriate flags. */ 1065 if (*ecp->cp == '-') 1066 FL_SET(ecp->iflags, E_C_COUNT_NEG); 1067 else if (*ecp->cp == '+') 1068 FL_SET(ecp->iflags, E_C_COUNT_POS); 1069 if ((nret = 1070 nget_slong(sp, <mp, ecp->cp, &t, 10)) != NUM_OK) { 1071 ex_badaddr(sp, NULL, A_NOTSET, nret); 1072 goto err; 1073 } 1074 if (ltmp == 0 && *np != '0') { 1075 msgq(sp, M_ERR, "083|Count may not be zero"); 1076 goto err; 1077 } 1078 ecp->clen -= (t - ecp->cp); 1079 ecp->cp = t; 1080 1081 /* 1082 * Counts as address offsets occur in commands taking 1083 * two addresses. Historic vi practice was to use 1084 * the count as an offset from the *second* address. 1085 * 1086 * Set a count flag; some underlying commands (see 1087 * join) do different things with counts than with 1088 * line addresses. 1089 */ 1090 if (*np == 'a') { 1091 ecp->addr1 = ecp->addr2; 1092 ecp->addr2.lno = ecp->addr1.lno + ltmp - 1; 1093 } else 1094 ecp->count = ltmp; 1095 FL_SET(ecp->iflags, E_C_COUNT); 1096 break; 1097 case 'f': /* file */ 1098 if (argv_exp2(sp, ecp, ecp->cp, ecp->clen)) 1099 goto err; 1100 goto arg_cnt_chk; 1101 case 'l': /* line */ 1102 /* 1103 * Get a line specification. 1104 * 1105 * If the line was a search expression, we may have 1106 * changed state during the call, and we're now 1107 * searching the file. Push ourselves onto the state 1108 * stack. 1109 */ 1110 if (ex_line(sp, ecp, &cur, &isaddr, &tmp)) 1111 goto rfail; 1112 if (tmp) 1113 goto err; 1114 1115 /* Line specifications are always required. */ 1116 if (!isaddr) { 1117 msgq_wstr(sp, M_ERR, ecp->cp, 1118 "084|%s: bad line specification"); 1119 goto err; 1120 } 1121 /* 1122 * The target line should exist for these commands, 1123 * but 0 is legal for them as well. 1124 */ 1125 if (cur.lno != 0 && !db_exist(sp, cur.lno)) { 1126 ex_badaddr(sp, NULL, A_EOF, NUM_OK); 1127 goto err; 1128 } 1129 ecp->lineno = cur.lno; 1130 break; 1131 case 'S': /* string, file exp. */ 1132 if (ecp->clen != 0) { 1133 if (argv_exp1(sp, ecp, ecp->cp, 1134 ecp->clen, ecp->cmd == &cmds[C_BANG])) 1135 goto err; 1136 goto addr_verify; 1137 } 1138 /* FALLTHROUGH */ 1139 case 's': /* string */ 1140 if (argv_exp0(sp, ecp, ecp->cp, ecp->clen)) 1141 goto err; 1142 goto addr_verify; 1143 case 'W': /* word string */ 1144 /* 1145 * QUOTING NOTE: 1146 * 1147 * Literal next characters escape the following 1148 * character. Quoting characters are stripped here 1149 * since they are no longer useful. 1150 * 1151 * First there was the word. 1152 */ 1153 for (p = t = ecp->cp; 1154 ecp->clen > 0; --ecp->clen, ++ecp->cp) { 1155 ch = (UCHAR_T)*ecp->cp; 1156 if (IS_ESCAPE(sp, 1157 ecp, ch) && ecp->clen > 1) { 1158 --ecp->clen; 1159 *p++ = *++ecp->cp; 1160 } else if (ISBLANK(ch)) { 1161 ++ecp->cp; 1162 --ecp->clen; 1163 break; 1164 } else 1165 *p++ = ch; 1166 } 1167 if (argv_exp0(sp, ecp, t, p - t)) 1168 goto err; 1169 1170 /* Delete intervening whitespace. */ 1171 for (; ecp->clen > 0; 1172 --ecp->clen, ++ecp->cp) { 1173 ch = (UCHAR_T)*ecp->cp; 1174 if (!ISBLANK(ch)) 1175 break; 1176 } 1177 if (ecp->clen == 0) 1178 goto usage; 1179 1180 /* Followed by the string. */ 1181 for (p = t = ecp->cp; ecp->clen > 0; 1182 --ecp->clen, ++ecp->cp, ++p) { 1183 ch = (UCHAR_T)*ecp->cp; 1184 if (IS_ESCAPE(sp, 1185 ecp, ch) && ecp->clen > 1) { 1186 --ecp->clen; 1187 *p = *++ecp->cp; 1188 } else 1189 *p = ch; 1190 } 1191 if (argv_exp0(sp, ecp, t, p - t)) 1192 goto err; 1193 goto addr_verify; 1194 case 'w': /* word */ 1195 if (argv_exp3(sp, ecp, ecp->cp, ecp->clen)) 1196 goto err; 1197 arg_cnt_chk: if (*++np != 'N') { /* N */ 1198 /* 1199 * If a number is specified, must either be 1200 * 0 or that number, if optional, and that 1201 * number, if required. 1202 */ 1203 tmp = *np - '0'; 1204 if ((*++np != 'o' || exp->argsoff != 0) && 1205 exp->argsoff != tmp) 1206 goto usage; 1207 } 1208 goto addr_verify; 1209 default: { 1210 const char *nstr; 1211 size_t nlen; 1212 INT2CHAR(sp, ecp->cmd->name, STRLEN(ecp->cmd->name) + 1, 1213 nstr, nlen); 1214 msgq(sp, M_ERR, 1215 "085|Internal syntax table error (%s: %s)", 1216 nstr, KEY_NAME(sp, *np)); 1217 } 1218 } 1219 } 1220 1221 /* Skip trailing whitespace. */ 1222 for (; ecp->clen > 0; --ecp->clen) { 1223 ch = (UCHAR_T)*ecp->cp++; 1224 if (!ISBLANK(ch)) 1225 break; 1226 } 1227 1228 /* 1229 * There shouldn't be anything left, and no more required fields, 1230 * i.e neither 'l' or 'r' in the syntax string. 1231 */ 1232 if (ecp->clen != 0 || strpbrk(np, "lr")) { 1233 usage: msgq(sp, M_ERR, "086|Usage: %s", ecp->cmd->usage); 1234 goto err; 1235 } 1236 1237 /* 1238 * Verify that the addresses are legal. Check the addresses here, 1239 * because this is a place where all ex addresses pass through. 1240 * (They don't all pass through ex_line(), for instance.) We're 1241 * assuming that any non-existent line doesn't exist because it's 1242 * past the end-of-file. That's a pretty good guess. 1243 * 1244 * If it's a "default vi command", an address of zero is okay. 1245 */ 1246 addr_verify: 1247 switch (ecp->addrcnt) { 1248 case 2: 1249 /* 1250 * Historic ex/vi permitted commands with counts to go past 1251 * EOF. So, for example, if the file only had 5 lines, the 1252 * ex command "1,6>" would fail, but the command ">300" 1253 * would succeed. Since we don't want to have to make all 1254 * of the underlying commands handle random line numbers, 1255 * fix it here. 1256 */ 1257 if (ecp->addr2.lno == 0) { 1258 if (!F_ISSET(ecp, E_ADDR_ZERO) && 1259 (F_ISSET(sp, SC_EX) || 1260 !F_ISSET(ecp, E_USELASTCMD))) { 1261 ex_badaddr(sp, ecp->cmd, A_ZERO, NUM_OK); 1262 goto err; 1263 } 1264 } else if (!db_exist(sp, ecp->addr2.lno)) { 1265 if (FL_ISSET(ecp->iflags, E_C_COUNT)) { 1266 if (db_last(sp, &lno)) 1267 goto err; 1268 ecp->addr2.lno = lno; 1269 } else { 1270 ex_badaddr(sp, NULL, A_EOF, NUM_OK); 1271 goto err; 1272 } 1273 } 1274 /* FALLTHROUGH */ 1275 case 1: 1276 if (ecp->addr1.lno == 0) { 1277 if (!F_ISSET(ecp, E_ADDR_ZERO) && 1278 (F_ISSET(sp, SC_EX) || 1279 !F_ISSET(ecp, E_USELASTCMD))) { 1280 ex_badaddr(sp, ecp->cmd, A_ZERO, NUM_OK); 1281 goto err; 1282 } 1283 } else if (!db_exist(sp, ecp->addr1.lno)) { 1284 ex_badaddr(sp, NULL, A_EOF, NUM_OK); 1285 goto err; 1286 } 1287 break; 1288 } 1289 1290 /* 1291 * If doing a default command and there's nothing left on the line, 1292 * vi just moves to the line. For example, ":3" and ":'a,'b" just 1293 * move to line 3 and line 'b, respectively, but ":3|" prints line 3. 1294 * 1295 * !!! 1296 * In addition, IF THE LINE CHANGES, move to the first nonblank of 1297 * the line. 1298 * 1299 * !!! 1300 * This is done before the absolute mark gets set; historically, 1301 * "/a/,/b/" did NOT set vi's absolute mark, but "/a/,/b/d" did. 1302 */ 1303 if ((F_ISSET(sp, SC_VI) || F_ISSET(ecp, E_NOPRDEF)) && 1304 F_ISSET(ecp, E_USELASTCMD) && vi_address == 0) { 1305 switch (ecp->addrcnt) { 1306 case 2: 1307 if (sp->lno != 1308 (ecp->addr2.lno ? ecp->addr2.lno : 1)) { 1309 sp->lno = 1310 ecp->addr2.lno ? ecp->addr2.lno : 1; 1311 sp->cno = 0; 1312 (void)nonblank(sp, sp->lno, &sp->cno); 1313 } 1314 break; 1315 case 1: 1316 if (sp->lno != 1317 (ecp->addr1.lno ? ecp->addr1.lno : 1)) { 1318 sp->lno = 1319 ecp->addr1.lno ? ecp->addr1.lno : 1; 1320 sp->cno = 0; 1321 (void)nonblank(sp, sp->lno, &sp->cno); 1322 } 1323 break; 1324 } 1325 ecp->cp = ecp->save_cmd; 1326 ecp->clen = ecp->save_cmdlen; 1327 goto loop; 1328 } 1329 1330 /* 1331 * Set the absolute mark -- we have to set it for vi here, in case 1332 * it's a compound command, e.g. ":5p|6" should set the absolute 1333 * mark for vi. 1334 */ 1335 if (F_ISSET(ecp, E_ABSMARK)) { 1336 cur.lno = sp->lno; 1337 cur.cno = sp->cno; 1338 F_CLR(ecp, E_ABSMARK); 1339 if (mark_set(sp, ABSMARK1, &cur, 1)) 1340 goto err; 1341 } 1342 1343 #if defined(DEBUG) && defined(COMLOG) 1344 ex_comlog(sp, ecp); 1345 #endif 1346 /* Increment the command count if not called from vi. */ 1347 if (F_ISSET(sp, SC_EX)) 1348 ++sp->ccnt; 1349 1350 /* 1351 * If file state available, and not doing a global command, 1352 * log the start of an action. 1353 */ 1354 if (sp->ep != NULL && !F_ISSET(sp, SC_EX_GLOBAL)) 1355 (void)log_cursor(sp); 1356 1357 /* 1358 * !!! 1359 * There are two special commands for the purposes of this code: the 1360 * default command (<carriage-return>) or the scrolling commands (^D 1361 * and <EOF>) as the first non-<blank> characters in the line. 1362 * 1363 * If this is the first command in the command line, we received the 1364 * command from the ex command loop and we're talking to a tty, and 1365 * and there's nothing else on the command line, and it's one of the 1366 * special commands, we move back up to the previous line, and erase 1367 * the prompt character with the output. Since ex runs in canonical 1368 * mode, we don't have to do anything else, a <newline> has already 1369 * been echoed by the tty driver. It's OK if vi calls us -- we won't 1370 * be in ex mode so we'll do nothing. 1371 */ 1372 if (F_ISSET(ecp, E_NRSEP)) { 1373 if (sp->ep != NULL && 1374 F_ISSET(sp, SC_EX) && !F_ISSET(gp, G_SCRIPTED) && 1375 (F_ISSET(ecp, E_USELASTCMD) || ecp->cmd == &cmds[C_SCROLL])) 1376 gp->scr_ex_adjust(sp, EX_TERM_SCROLL); 1377 F_CLR(ecp, E_NRSEP); 1378 } 1379 1380 /* 1381 * Call the underlying function for the ex command. 1382 * 1383 * XXX 1384 * Interrupts behave like errors, for now. 1385 */ 1386 if (ecp->cmd->fn(sp, ecp) || INTERRUPTED(sp)) { 1387 if (F_ISSET(gp, G_SCRIPTED)) 1388 F_SET(sp, SC_EXIT_FORCE); 1389 goto err; 1390 } 1391 1392 #ifdef DEBUG 1393 /* Make sure no function left global temporary space locked. */ 1394 if (F_ISSET(wp, W_TMP_INUSE)) { 1395 F_CLR(wp, W_TMP_INUSE); 1396 msgq(sp, M_ERR, "087|%s: temporary buffer not released", 1397 ecp->cmd->name); 1398 } 1399 #endif 1400 /* 1401 * Ex displayed the number of lines modified immediately after each 1402 * command, so the command "1,10d|1,10d" would display: 1403 * 1404 * 10 lines deleted 1405 * 10 lines deleted 1406 * <autoprint line> 1407 * 1408 * Executing ex commands from vi only reported the final modified 1409 * lines message -- that's wrong enough that we don't match it. 1410 */ 1411 if (F_ISSET(sp, SC_EX)) 1412 mod_rpt(sp); 1413 1414 /* 1415 * Integrate any offset parsed by the underlying command, and make 1416 * sure the referenced line exists. 1417 * 1418 * XXX 1419 * May not match historic practice (which I've never been able to 1420 * completely figure out.) For example, the '=' command from vi 1421 * mode often got the offset wrong, and complained it was too large, 1422 * but didn't seem to have a problem with the cursor. If anyone 1423 * complains, ask them how it's supposed to work, they might know. 1424 */ 1425 if (sp->ep != NULL && ecp->flagoff) { 1426 if (ecp->flagoff < 0) { 1427 if (sp->lno <= (db_recno_t)(-ecp->flagoff)) { 1428 msgq(sp, M_ERR, 1429 "088|Flag offset to before line 1"); 1430 goto err; 1431 } 1432 } else { 1433 if (!NPFITS(DB_MAX_RECORDS, sp->lno, (db_recno_t)ecp->flagoff)) { 1434 ex_badaddr(sp, NULL, A_NOTSET, NUM_OVER); 1435 goto err; 1436 } 1437 if (!db_exist(sp, sp->lno + ecp->flagoff)) { 1438 msgq(sp, M_ERR, 1439 "089|Flag offset past end-of-file"); 1440 goto err; 1441 } 1442 } 1443 sp->lno += ecp->flagoff; 1444 } 1445 1446 /* 1447 * If the command executed successfully, we may want to display a line 1448 * based on the autoprint option or an explicit print flag. (Make sure 1449 * that there's a line to display.) Also, the autoprint edit option is 1450 * turned off for the duration of global commands. 1451 */ 1452 if (F_ISSET(sp, SC_EX) && sp->ep != NULL && sp->lno != 0) { 1453 /* 1454 * The print commands have already handled the `print' flags. 1455 * If so, clear them. 1456 */ 1457 if (FL_ISSET(ecp->iflags, E_CLRFLAG)) 1458 FL_CLR(ecp->iflags, E_C_HASH | E_C_LIST | E_C_PRINT); 1459 1460 /* If hash set only because of the number option, discard it. */ 1461 if (F_ISSET(ecp, E_OPTNUM)) 1462 FL_CLR(ecp->iflags, E_C_HASH); 1463 1464 /* 1465 * If there was an explicit flag to display the new cursor line, 1466 * or autoprint is set and a change was made, display the line. 1467 * If any print flags were set use them, else default to print. 1468 */ 1469 LF_INIT(FL_ISSET(ecp->iflags, E_C_HASH | E_C_LIST | E_C_PRINT)); 1470 if (!LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT | E_NOAUTO) && 1471 !F_ISSET(sp, SC_EX_GLOBAL) && 1472 O_ISSET(sp, O_AUTOPRINT) && F_ISSET(ecp, E_AUTOPRINT)) 1473 LF_INIT(E_C_PRINT); 1474 1475 if (LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT)) { 1476 cur.lno = sp->lno; 1477 cur.cno = 0; 1478 (void)ex_print(sp, ecp, &cur, &cur, flags); 1479 } 1480 } 1481 1482 /* 1483 * If the command had an associated "+cmd", it has to be executed 1484 * before we finish executing any more of this ex command. For 1485 * example, consider a .exrc file that contains the following lines: 1486 * 1487 * :set all 1488 * :edit +25 file.c|s/abc/ABC/|1 1489 * :3,5 print 1490 * 1491 * This can happen more than once -- the historic vi simply hung or 1492 * dropped core, of course. Prepend the + command back into the 1493 * current command and continue. We may have to add an additional 1494 * <literal next> character. We know that it will fit because we 1495 * discarded at least one space and the + character. 1496 */ 1497 if (arg1_len != 0) { 1498 /* 1499 * If the last character of the + command was a <literal next> 1500 * character, it would be treated differently because of the 1501 * append. Quote it, if necessary. 1502 */ 1503 if (IS_ESCAPE(sp, ecp, arg1[arg1_len - 1])) { 1504 *--ecp->save_cmd = CH_LITERAL; 1505 ++ecp->save_cmdlen; 1506 } 1507 1508 ecp->save_cmd -= arg1_len; 1509 ecp->save_cmdlen += arg1_len; 1510 MEMCPYW(ecp->save_cmd, arg1, arg1_len); 1511 1512 /* 1513 * Any commands executed from a +cmd are executed starting at 1514 * the first column of the last line of the file -- NOT the 1515 * first nonblank.) The main file startup code doesn't know 1516 * that a +cmd was set, however, so it may have put us at the 1517 * top of the file. (Note, this is safe because we must have 1518 * switched files to get here.) 1519 */ 1520 F_SET(ecp, E_MOVETOEND); 1521 } 1522 1523 /* Update the current command. */ 1524 ecp->cp = ecp->save_cmd; 1525 ecp->clen = ecp->save_cmdlen; 1526 1527 /* 1528 * !!! 1529 * If we've changed screens or underlying files, any pending global or 1530 * v command, or @ buffer that has associated addresses, has to be 1531 * discarded. This is historic practice for globals, and necessary for 1532 * @ buffers that had associated addresses. 1533 * 1534 * Otherwise, if we've changed underlying files, it's not a problem, 1535 * we continue with the rest of the ex command(s), operating on the 1536 * new file. However, if we switch screens (either by exiting or by 1537 * an explicit command), we have no way of knowing where to put output 1538 * messages, and, since we don't control screens here, we could screw 1539 * up the upper layers, (e.g. we could exit/reenter a screen multiple 1540 * times). So, return and continue after we've got a new screen. 1541 */ 1542 if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE | SC_FSWITCH | SC_SSWITCH)) { 1543 at_found = gv_found = 0; 1544 for (ecp = wp->ecq.lh_first; 1545 ecp != NULL; ecp = ecp->q.le_next) 1546 switch (ecp->agv_flags) { 1547 case 0: 1548 case AGV_AT_NORANGE: 1549 break; 1550 case AGV_AT: 1551 if (!at_found) { 1552 at_found = 1; 1553 msgq(sp, M_ERR, 1554 "090|@ with range running when the file/screen changed"); 1555 } 1556 break; 1557 case AGV_GLOBAL: 1558 case AGV_V: 1559 if (!gv_found) { 1560 gv_found = 1; 1561 msgq(sp, M_ERR, 1562 "091|Global/v command running when the file/screen changed"); 1563 } 1564 break; 1565 default: 1566 abort(); 1567 } 1568 if (at_found || gv_found) 1569 goto discard; 1570 if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE | SC_SSWITCH)) 1571 goto rsuccess; 1572 } 1573 1574 goto loop; 1575 /* NOTREACHED */ 1576 1577 err: /* 1578 * On command failure, we discard keys and pending commands remaining, 1579 * as well as any keys that were mapped and waiting. The save_cmdlen 1580 * test is not necessarily correct. If we fail early enough we don't 1581 * know if the entire string was a single command or not. Guess, as 1582 * it's useful to know if commands other than the current one are being 1583 * discarded. 1584 */ 1585 if (ecp->save_cmdlen == 0) 1586 for (; ecp->clen; --ecp->clen) { 1587 ch = (UCHAR_T)*ecp->cp++; 1588 if (IS_ESCAPE(sp, ecp, ch) && ecp->clen > 1) { 1589 --ecp->clen; 1590 ++ecp->cp; 1591 } else if (ch == '\n' || ch == '|') { 1592 if (ecp->clen > 1) 1593 ecp->save_cmdlen = 1; 1594 break; 1595 } 1596 } 1597 if (ecp->save_cmdlen != 0 || wp->ecq.lh_first != &wp->excmd) { 1598 discard: msgq(sp, M_BERR, 1599 "092|Ex command failed: pending commands discarded"); 1600 ex_discard(sp); 1601 } 1602 if (v_event_flush(sp, CH_MAPPED)) 1603 msgq(sp, M_BERR, 1604 "093|Ex command failed: mapped keys discarded"); 1605 1606 rfail: tmp = 1; 1607 if (0) 1608 rsuccess: tmp = 0; 1609 1610 /* Turn off any file name error information. */ 1611 wp->if_name = NULL; 1612 1613 /* Turn off the global bit. */ 1614 F_CLR(sp, SC_EX_GLOBAL); 1615 1616 return (tmp); 1617 } 1618 1619 /* 1620 * ex_range -- 1621 * Get a line range for ex commands, or perform a vi ex address search. 1622 * 1623 * PUBLIC: int ex_range __P((SCR *, EXCMD *, int *)); 1624 */ 1625 int 1626 ex_range(SCR *sp, EXCMD *ecp, int *errp) 1627 { 1628 enum { ADDR_FOUND, ADDR_NEED, ADDR_NONE } addr; 1629 MARK m; 1630 int isaddr; 1631 1632 *errp = 0; 1633 1634 /* 1635 * Parse comma or semi-colon delimited line specs. 1636 * 1637 * Semi-colon delimiters update the current address to be the last 1638 * address. For example, the command 1639 * 1640 * :3;/pattern/ecp->cp 1641 * 1642 * will search for pattern from line 3. In addition, if ecp->cp 1643 * is not a valid command, the current line will be left at 3, not 1644 * at the original address. 1645 * 1646 * Extra addresses are discarded, starting with the first. 1647 * 1648 * !!! 1649 * If any addresses are missing, they default to the current line. 1650 * This was historically true for both leading and trailing comma 1651 * delimited addresses as well as for trailing semicolon delimited 1652 * addresses. For consistency, we make it true for leading semicolon 1653 * addresses as well. 1654 */ 1655 for (addr = ADDR_NONE, ecp->addrcnt = 0; ecp->clen > 0;) 1656 switch (*ecp->cp) { 1657 case '%': /* Entire file. */ 1658 /* Vi ex address searches didn't permit % signs. */ 1659 if (F_ISSET(ecp, E_VISEARCH)) 1660 goto ret; 1661 1662 /* It's an error if the file is empty. */ 1663 if (sp->ep == NULL) { 1664 ex_badaddr(sp, NULL, A_EMPTY, NUM_OK); 1665 *errp = 1; 1666 return (0); 1667 } 1668 /* 1669 * !!! 1670 * A percent character addresses all of the lines in 1671 * the file. Historically, it couldn't be followed by 1672 * any other address. We do it as a text substitution 1673 * for simplicity. POSIX 1003.2 is expected to follow 1674 * this practice. 1675 * 1676 * If it's an empty file, the first line is 0, not 1. 1677 */ 1678 if (addr == ADDR_FOUND) { 1679 ex_badaddr(sp, NULL, A_COMBO, NUM_OK); 1680 *errp = 1; 1681 return (0); 1682 } 1683 if (db_last(sp, &ecp->addr2.lno)) 1684 return (1); 1685 ecp->addr1.lno = ecp->addr2.lno == 0 ? 0 : 1; 1686 ecp->addr1.cno = ecp->addr2.cno = 0; 1687 ecp->addrcnt = 2; 1688 addr = ADDR_FOUND; 1689 ++ecp->cp; 1690 --ecp->clen; 1691 break; 1692 case ',': /* Comma delimiter. */ 1693 /* Vi ex address searches didn't permit commas. */ 1694 if (F_ISSET(ecp, E_VISEARCH)) 1695 goto ret; 1696 /* FALLTHROUGH */ 1697 case ';': /* Semi-colon delimiter. */ 1698 if (sp->ep == NULL) { 1699 ex_badaddr(sp, NULL, A_EMPTY, NUM_OK); 1700 *errp = 1; 1701 return (0); 1702 } 1703 if (addr != ADDR_FOUND) 1704 switch (ecp->addrcnt) { 1705 case 0: 1706 ecp->addr1.lno = sp->lno; 1707 ecp->addr1.cno = sp->cno; 1708 ecp->addrcnt = 1; 1709 break; 1710 case 2: 1711 ecp->addr1 = ecp->addr2; 1712 /* FALLTHROUGH */ 1713 case 1: 1714 ecp->addr2.lno = sp->lno; 1715 ecp->addr2.cno = sp->cno; 1716 ecp->addrcnt = 2; 1717 break; 1718 } 1719 if (*ecp->cp == ';') 1720 switch (ecp->addrcnt) { 1721 case 0: 1722 abort(); 1723 /* NOTREACHED */ 1724 case 1: 1725 sp->lno = ecp->addr1.lno; 1726 sp->cno = ecp->addr1.cno; 1727 break; 1728 case 2: 1729 sp->lno = ecp->addr2.lno; 1730 sp->cno = ecp->addr2.cno; 1731 break; 1732 } 1733 addr = ADDR_NEED; 1734 /* FALLTHROUGH */ 1735 case ' ': /* Whitespace. */ 1736 case '\t': /* Whitespace. */ 1737 ++ecp->cp; 1738 --ecp->clen; 1739 break; 1740 default: 1741 /* Get a line specification. */ 1742 if (ex_line(sp, ecp, &m, &isaddr, errp)) 1743 return (1); 1744 if (*errp) 1745 return (0); 1746 if (!isaddr) 1747 goto ret; 1748 if (addr == ADDR_FOUND) { 1749 ex_badaddr(sp, NULL, A_COMBO, NUM_OK); 1750 *errp = 1; 1751 return (0); 1752 } 1753 switch (ecp->addrcnt) { 1754 case 0: 1755 ecp->addr1 = m; 1756 ecp->addrcnt = 1; 1757 break; 1758 case 1: 1759 ecp->addr2 = m; 1760 ecp->addrcnt = 2; 1761 break; 1762 case 2: 1763 ecp->addr1 = ecp->addr2; 1764 ecp->addr2 = m; 1765 break; 1766 } 1767 addr = ADDR_FOUND; 1768 break; 1769 } 1770 1771 /* 1772 * !!! 1773 * Vi ex address searches are indifferent to order or trailing 1774 * semi-colons. 1775 */ 1776 ret: if (F_ISSET(ecp, E_VISEARCH)) 1777 return (0); 1778 1779 if (addr == ADDR_NEED) 1780 switch (ecp->addrcnt) { 1781 case 0: 1782 ecp->addr1.lno = sp->lno; 1783 ecp->addr1.cno = sp->cno; 1784 ecp->addrcnt = 1; 1785 break; 1786 case 2: 1787 ecp->addr1 = ecp->addr2; 1788 /* FALLTHROUGH */ 1789 case 1: 1790 ecp->addr2.lno = sp->lno; 1791 ecp->addr2.cno = sp->cno; 1792 ecp->addrcnt = 2; 1793 break; 1794 } 1795 1796 if (ecp->addrcnt == 2 && ecp->addr2.lno < ecp->addr1.lno) { 1797 msgq(sp, M_ERR, 1798 "094|The second address is smaller than the first"); 1799 *errp = 1; 1800 } 1801 return (0); 1802 } 1803 1804 /* 1805 * ex_line -- 1806 * Get a single line address specifier. 1807 * 1808 * The way the "previous context" mark worked was that any "non-relative" 1809 * motion set it. While ex/vi wasn't totally consistent about this, ANY 1810 * numeric address, search pattern, '$', or mark reference in an address 1811 * was considered non-relative, and set the value. Which should explain 1812 * why we're hacking marks down here. The problem was that the mark was 1813 * only set if the command was called, i.e. we have to set a flag and test 1814 * it later. 1815 * 1816 * XXX 1817 * This is probably still not exactly historic practice, although I think 1818 * it's fairly close. 1819 */ 1820 static int 1821 ex_line(SCR *sp, EXCMD *ecp, MARK *mp, int *isaddrp, int *errp) 1822 { 1823 enum nresult nret; 1824 long total, val; 1825 unsigned long uval; 1826 int isneg; 1827 int (*sf) __P((SCR *, MARK *, MARK *, CHAR_T *, size_t, CHAR_T **, u_int)); 1828 CHAR_T *endp; 1829 1830 *isaddrp = *errp = 0; 1831 F_CLR(ecp, E_DELTA); 1832 1833 /* No addresses permitted until a file has been read in. */ 1834 if (sp->ep == NULL && STRCHR(L("$0123456789'\\/?.+-^"), *ecp->cp)) { 1835 ex_badaddr(sp, NULL, A_EMPTY, NUM_OK); 1836 *errp = 1; 1837 return (0); 1838 } 1839 1840 switch (*ecp->cp) { 1841 case '$': /* Last line in the file. */ 1842 *isaddrp = 1; 1843 F_SET(ecp, E_ABSMARK); 1844 1845 mp->cno = 0; 1846 if (db_last(sp, &mp->lno)) 1847 return (1); 1848 ++ecp->cp; 1849 --ecp->clen; 1850 break; /* Absolute line number. */ 1851 case '0': case '1': case '2': case '3': case '4': 1852 case '5': case '6': case '7': case '8': case '9': 1853 *isaddrp = 1; 1854 F_SET(ecp, E_ABSMARK); 1855 1856 if ((nret = nget_uslong(sp, &uval, ecp->cp, &endp, 10)) != NUM_OK) { 1857 ex_badaddr(sp, NULL, A_NOTSET, nret); 1858 *errp = 1; 1859 return (0); 1860 } 1861 if (!NPFITS(DB_MAX_RECORDS, 0, uval)) { 1862 ex_badaddr(sp, NULL, A_NOTSET, NUM_OVER); 1863 *errp = 1; 1864 return (0); 1865 } 1866 mp->lno = uval; 1867 mp->cno = 0; 1868 ecp->clen -= (endp - ecp->cp); 1869 ecp->cp = endp; 1870 break; 1871 case '\'': /* Use a mark. */ 1872 *isaddrp = 1; 1873 F_SET(ecp, E_ABSMARK); 1874 1875 if (ecp->clen == 1) { 1876 msgq(sp, M_ERR, "095|No mark name supplied"); 1877 *errp = 1; 1878 return (0); 1879 } 1880 if (mark_get(sp, ecp->cp[1], mp, M_ERR)) { 1881 *errp = 1; 1882 return (0); 1883 } 1884 ecp->cp += 2; 1885 ecp->clen -= 2; 1886 break; 1887 case '\\': /* Search: forward/backward. */ 1888 /* 1889 * !!! 1890 * I can't find any difference between // and \/ or between 1891 * ?? and \?. Mark Horton doesn't remember there being any 1892 * difference. C'est la vie. 1893 */ 1894 if (ecp->clen < 2 || 1895 (ecp->cp[1] != '/' && ecp->cp[1] != '?')) { 1896 msgq(sp, M_ERR, "096|\\ not followed by / or ?"); 1897 *errp = 1; 1898 return (0); 1899 } 1900 ++ecp->cp; 1901 --ecp->clen; 1902 sf = ecp->cp[0] == '/' ? f_search : b_search; 1903 goto search; 1904 case '/': /* Search forward. */ 1905 sf = f_search; 1906 goto search; 1907 case '?': /* Search backward. */ 1908 sf = b_search; 1909 1910 search: mp->lno = sp->lno; 1911 mp->cno = sp->cno; 1912 if (sf(sp, mp, mp, ecp->cp, ecp->clen, &endp, 1913 SEARCH_MSG | SEARCH_PARSE | SEARCH_SET | 1914 (F_ISSET(ecp, E_SEARCH_WMSG) ? SEARCH_WMSG : 0))) { 1915 *errp = 1; 1916 return (0); 1917 } 1918 1919 /* Fix up the command pointers. */ 1920 ecp->clen -= (endp - ecp->cp); 1921 ecp->cp = endp; 1922 1923 *isaddrp = 1; 1924 F_SET(ecp, E_ABSMARK); 1925 break; 1926 case '.': /* Current position. */ 1927 *isaddrp = 1; 1928 mp->cno = sp->cno; 1929 1930 /* If an empty file, then '.' is 0, not 1. */ 1931 if (sp->lno == 1) { 1932 if (db_last(sp, &mp->lno)) 1933 return (1); 1934 if (mp->lno != 0) 1935 mp->lno = 1; 1936 } else 1937 mp->lno = sp->lno; 1938 1939 /* 1940 * !!! 1941 * Historically, .<number> was the same as .+<number>, i.e. 1942 * the '+' could be omitted. (This feature is found in ed 1943 * as well.) 1944 */ 1945 if (ecp->clen > 1 && ISDIGIT((UCHAR_T)ecp->cp[1])) 1946 *ecp->cp = '+'; 1947 else { 1948 ++ecp->cp; 1949 --ecp->clen; 1950 } 1951 break; 1952 } 1953 1954 /* Skip trailing <blank>s. */ 1955 for (; ecp->clen > 0 && 1956 ISBLANK((UCHAR_T)ecp->cp[0]); ++ecp->cp, --ecp->clen); 1957 1958 /* 1959 * Evaluate any offset. If no address yet found, the offset 1960 * is relative to ".". 1961 */ 1962 total = 0; 1963 if (ecp->clen != 0 && (ISDIGIT((UCHAR_T)ecp->cp[0]) || 1964 ecp->cp[0] == '+' || ecp->cp[0] == '-' || 1965 ecp->cp[0] == '^')) { 1966 if (!*isaddrp) { 1967 *isaddrp = 1; 1968 mp->lno = sp->lno; 1969 mp->cno = sp->cno; 1970 } 1971 /* 1972 * Evaluate an offset, defined as: 1973 * 1974 * [+-^<blank>]*[<blank>]*[0-9]* 1975 * 1976 * The rough translation is any number of signs, optionally 1977 * followed by numbers, or a number by itself, all <blank> 1978 * separated. 1979 * 1980 * !!! 1981 * All address offsets were additive, e.g. "2 2 3p" was the 1982 * same as "7p", or, "/ZZZ/ 2" was the same as "/ZZZ/+2". 1983 * Note, however, "2 /ZZZ/" was an error. It was also legal 1984 * to insert signs without numbers, so "3 - 2" was legal, and 1985 * equal to 4. 1986 * 1987 * !!! 1988 * Offsets were historically permitted for any line address, 1989 * e.g. the command "1,2 copy 2 2 2 2" copied lines 1,2 after 1990 * line 8. 1991 * 1992 * !!! 1993 * Offsets were historically permitted for search commands, 1994 * and handled as addresses: "/pattern/2 2 2" was legal, and 1995 * referenced the 6th line after pattern. 1996 */ 1997 F_SET(ecp, E_DELTA); 1998 for (;;) { 1999 for (; ecp->clen > 0 && ISBLANK((UCHAR_T)ecp->cp[0]); 2000 ++ecp->cp, --ecp->clen); 2001 if (ecp->clen == 0 || (!ISDIGIT((UCHAR_T)ecp->cp[0]) && 2002 ecp->cp[0] != '+' && ecp->cp[0] != '-' && 2003 ecp->cp[0] != '^')) 2004 break; 2005 if (!ISDIGIT((UCHAR_T)ecp->cp[0]) && 2006 !ISDIGIT((UCHAR_T)ecp->cp[1])) { 2007 total += ecp->cp[0] == '+' ? 1 : -1; 2008 --ecp->clen; 2009 ++ecp->cp; 2010 } else { 2011 if (ecp->cp[0] == '-' || 2012 ecp->cp[0] == '^') { 2013 ++ecp->cp; 2014 --ecp->clen; 2015 isneg = 1; 2016 } else 2017 isneg = 0; 2018 2019 /* Get a signed long, add it to the total. */ 2020 if ((nret = nget_slong(sp, &val, 2021 ecp->cp, &endp, 10)) != NUM_OK || 2022 (nret = NADD_SLONG(sp, 2023 total, val)) != NUM_OK) { 2024 ex_badaddr(sp, NULL, A_NOTSET, nret); 2025 *errp = 1; 2026 return (0); 2027 } 2028 total += isneg ? -val : val; 2029 ecp->clen -= (endp - ecp->cp); 2030 ecp->cp = endp; 2031 } 2032 } 2033 } 2034 2035 /* 2036 * Any value less than 0 is an error. Make sure that the new value 2037 * will fit into a db_recno_t. 2038 */ 2039 if (*isaddrp && total != 0) { 2040 if (total < 0) { 2041 if ((db_recno_t)-total > mp->lno) { 2042 msgq(sp, M_ERR, 2043 "097|Reference to a line number less than 0"); 2044 *errp = 1; 2045 return (0); 2046 } 2047 } else 2048 if (!NPFITS(DB_MAX_RECORDS, mp->lno, (unsigned long)total)) { 2049 ex_badaddr(sp, NULL, A_NOTSET, NUM_OVER); 2050 *errp = 1; 2051 return (0); 2052 } 2053 mp->lno += total; 2054 } 2055 return (0); 2056 } 2057 2058 2059 /* 2060 * ex_load -- 2061 * Load up the next command, which may be an @ buffer or global command. 2062 */ 2063 static int 2064 ex_load(SCR *sp) 2065 { 2066 WIN *wp; 2067 EXCMD *ecp; 2068 RANGE *rp; 2069 2070 F_CLR(sp, SC_EX_GLOBAL); 2071 2072 /* 2073 * Lose any exhausted commands. We know that the first command 2074 * can't be an AGV command, which makes things a bit easier. 2075 */ 2076 for (wp = sp->wp;;) { 2077 /* 2078 * If we're back to the original structure, leave it around, 2079 * but discard any allocated source name, we've returned to 2080 * the beginning of the command stack. 2081 */ 2082 if ((ecp = wp->ecq.lh_first) == &wp->excmd) { 2083 if (F_ISSET(ecp, E_NAMEDISCARD)) { 2084 free(ecp->if_name); 2085 ecp->if_name = NULL; 2086 } 2087 return (0); 2088 } 2089 2090 /* 2091 * ecp->clen will be 0 for the first discarded command, but 2092 * may not be 0 for subsequent ones, e.g. if the original 2093 * command was ":g/xx/@a|s/b/c/", then when we discard the 2094 * command pushed on the stack by the @a, we have to resume 2095 * the global command which included the substitute command. 2096 */ 2097 if (ecp->clen != 0) 2098 return (0); 2099 2100 /* 2101 * If it's an @, global or v command, we may need to continue 2102 * the command on a different line. 2103 */ 2104 if (FL_ISSET(ecp->agv_flags, AGV_ALL)) { 2105 /* Discard any exhausted ranges. */ 2106 while ((rp = ecp->rq.cqh_first) != (void *)&ecp->rq) 2107 if (rp->start > rp->stop) { 2108 CIRCLEQ_REMOVE(&ecp->rq, rp, q); 2109 free(rp); 2110 } else 2111 break; 2112 2113 /* If there's another range, continue with it. */ 2114 if (rp != (void *)&ecp->rq) 2115 break; 2116 2117 /* If it's a global/v command, fix up the last line. */ 2118 if (FL_ISSET(ecp->agv_flags, 2119 AGV_GLOBAL | AGV_V) && ecp->range_lno != OOBLNO) { 2120 if (db_exist(sp, ecp->range_lno)) 2121 sp->lno = ecp->range_lno; 2122 else { 2123 if (db_last(sp, &sp->lno)) 2124 return (1); 2125 if (sp->lno == 0) 2126 sp->lno = 1; 2127 } 2128 } 2129 free(ecp->o_cp); 2130 } 2131 2132 /* Discard the EXCMD. */ 2133 LIST_REMOVE(ecp, q); 2134 free(ecp); 2135 } 2136 2137 /* 2138 * We only get here if it's an active @, global or v command. Set 2139 * the current line number, and get a new copy of the command for 2140 * the parser. Note, the original pointer almost certainly moved, 2141 * so we have play games. 2142 */ 2143 ecp->cp = ecp->o_cp; 2144 MEMCPYW(ecp->cp, ecp->cp + ecp->o_clen, ecp->o_clen); 2145 ecp->clen = ecp->o_clen; 2146 ecp->range_lno = sp->lno = rp->start++; 2147 2148 if (FL_ISSET(ecp->agv_flags, AGV_GLOBAL | AGV_V)) 2149 F_SET(sp, SC_EX_GLOBAL); 2150 return (0); 2151 } 2152 2153 /* 2154 * ex_discard -- 2155 * Discard any pending ex commands. 2156 */ 2157 static int 2158 ex_discard(SCR *sp) 2159 { 2160 WIN *wp; 2161 EXCMD *ecp; 2162 RANGE *rp; 2163 2164 /* 2165 * We know the first command can't be an AGV command, so we don't 2166 * process it specially. We do, however, nail the command itself. 2167 */ 2168 for (wp = sp->wp; (ecp = wp->ecq.lh_first) != &wp->excmd;) { 2169 if (FL_ISSET(ecp->agv_flags, AGV_ALL)) { 2170 while ((rp = ecp->rq.cqh_first) != (void *)&ecp->rq) { 2171 CIRCLEQ_REMOVE(&ecp->rq, rp, q); 2172 free(rp); 2173 } 2174 free(ecp->o_cp); 2175 } 2176 LIST_REMOVE(ecp, q); 2177 free(ecp); 2178 } 2179 wp->ecq.lh_first->clen = 0; 2180 return (0); 2181 } 2182 2183 /* 2184 * ex_unknown -- 2185 * Display an unknown command name. 2186 */ 2187 static void 2188 ex_unknown(SCR *sp, CHAR_T *cmd, size_t len) 2189 { 2190 size_t blen; 2191 CHAR_T *bp; 2192 2193 GET_SPACE_GOTOW(sp, bp, blen, len + 1); 2194 bp[len] = '\0'; 2195 MEMCPYW(bp, cmd, len); 2196 msgq_wstr(sp, M_ERR, bp, "098|The %s command is unknown"); 2197 FREE_SPACEW(sp, bp, blen); 2198 2199 alloc_err: 2200 return; 2201 } 2202 2203 /* 2204 * ex_is_abbrev - 2205 * The vi text input routine needs to know if ex thinks this is an 2206 * [un]abbreviate command, so it can turn off abbreviations. See 2207 * the usual ranting in the vi/v_txt_ev.c:txt_abbrev() routine. 2208 * 2209 * PUBLIC: int ex_is_abbrev __P((SCR *, CHAR_T *, size_t)); 2210 */ 2211 int 2212 ex_is_abbrev(SCR *sp, CHAR_T *name, size_t len) 2213 { 2214 EXCMDLIST const *cp; 2215 2216 return ((cp = ex_comm_search(sp, name, len)) != NULL && 2217 (cp == &cmds[C_ABBR] || cp == &cmds[C_UNABBREVIATE])); 2218 } 2219 2220 /* 2221 * ex_is_unmap - 2222 * The vi text input routine needs to know if ex thinks this is an 2223 * unmap command, so it can turn off input mapping. See the usual 2224 * ranting in the vi/v_txt_ev.c:txt_unmap() routine. 2225 * 2226 * PUBLIC: int ex_is_unmap __P((SCR *, CHAR_T *, size_t)); 2227 */ 2228 int 2229 ex_is_unmap(SCR *sp, CHAR_T *name, size_t len) 2230 { 2231 EXCMDLIST const *cp; 2232 2233 /* 2234 * The command the vi input routines are really interested in 2235 * is "unmap!", not just unmap. 2236 */ 2237 if (name[len - 1] != '!') 2238 return (0); 2239 --len; 2240 return ((cp = ex_comm_search(sp, name, len)) != NULL && 2241 cp == &cmds[C_UNMAP]); 2242 } 2243 2244 /* 2245 * ex_comm_search -- 2246 * Search for a command name. 2247 */ 2248 static EXCMDLIST const * 2249 ex_comm_search(SCR *sp, CHAR_T *name, size_t len) 2250 { 2251 EXCMDLIST const *cp; 2252 2253 for (cp = cmds; cp->name != NULL; ++cp) { 2254 if (cp->name[0] > name[0]) 2255 return (NULL); 2256 if (cp->name[0] != name[0]) 2257 continue; 2258 if (!MEMCMP(name, cp->name, len)) 2259 return (cp); 2260 } 2261 return (NULL); 2262 } 2263 2264 /* 2265 * ex_badaddr -- 2266 * Display a bad address message. 2267 * 2268 * PUBLIC: void ex_badaddr 2269 * PUBLIC: __P((SCR *, EXCMDLIST const *, enum badaddr, enum nresult)); 2270 */ 2271 void 2272 ex_badaddr(SCR *sp, const EXCMDLIST *cp, enum badaddr ba, enum nresult nret) 2273 { 2274 db_recno_t lno; 2275 2276 switch (nret) { 2277 case NUM_OK: 2278 break; 2279 case NUM_ERR: 2280 msgq(sp, M_SYSERR, NULL); 2281 return; 2282 case NUM_OVER: 2283 msgq(sp, M_ERR, "099|Address value overflow"); 2284 return; 2285 case NUM_UNDER: 2286 msgq(sp, M_ERR, "100|Address value underflow"); 2287 return; 2288 } 2289 2290 /* 2291 * When encountering an address error, tell the user if there's no 2292 * underlying file, that's the real problem. 2293 */ 2294 if (sp->ep == NULL) { 2295 ex_wemsg(sp, cp ? cp->name : NULL, EXM_NOFILEYET); 2296 return; 2297 } 2298 2299 switch (ba) { 2300 case A_COMBO: 2301 msgq(sp, M_ERR, "101|Illegal address combination"); 2302 break; 2303 case A_EOF: 2304 if (db_last(sp, &lno)) 2305 return; 2306 if (lno != 0) { 2307 msgq(sp, M_ERR, 2308 "102|Illegal address: only %lu lines in the file", 2309 (unsigned long)lno); 2310 break; 2311 } 2312 /* FALLTHROUGH */ 2313 case A_EMPTY: 2314 msgq(sp, M_ERR, "103|Illegal address: the file is empty"); 2315 break; 2316 case A_NOTSET: 2317 abort(); 2318 /* NOTREACHED */ 2319 case A_ZERO: 2320 msgq_wstr(sp, M_ERR, cp->name, 2321 "104|The %s command doesn't permit an address of 0"); 2322 break; 2323 } 2324 return; 2325 } 2326 2327 #if defined(DEBUG) && defined(COMLOG) 2328 /* 2329 * ex_comlog -- 2330 * Log ex commands. 2331 */ 2332 static void 2333 ex_comlog(sp, ecp) 2334 SCR *sp; 2335 EXCMD *ecp; 2336 { 2337 vtrace(sp, "ecmd: %s", ecp->cmd->name); 2338 if (ecp->addrcnt > 0) { 2339 vtrace(sp, " a1 %d", ecp->addr1.lno); 2340 if (ecp->addrcnt > 1) 2341 vtrace(sp, " a2: %d", ecp->addr2.lno); 2342 } 2343 if (ecp->lineno) 2344 vtrace(sp, " line %d", ecp->lineno); 2345 if (ecp->flags) 2346 vtrace(sp, " flags 0x%x", ecp->flags); 2347 if (F_ISSET(&exc, E_BUFFER)) 2348 vtrace(sp, " buffer "WC, ecp->buffer); 2349 if (ecp->argc) 2350 for (cnt = 0; cnt < ecp->argc; ++cnt) 2351 vtrace(sp, " arg %d: {%s}", cnt, ecp->argv[cnt]->bp); 2352 vtrace(sp, "\n"); 2353 } 2354 #endif 2355