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