1: /* Copyright (c) 1979 Regents of the University of California */
   2: #include "ex.h"
   3: #include "ex_argv.h"
   4: #include "ex_temp.h"
   5: #include "ex_tty.h"
   6: 
   7: bool    pflag, nflag;
   8: int poffset;
   9: 
  10: #define nochng()    lchng = chng
  11: 
  12: /*
  13:  * Main loop for command mode command decoding.
  14:  * A few commands are executed here, but main function
  15:  * is to strip command addresses, do a little address oriented
  16:  * processing and call command routines to do the real work.
  17:  */
  18: commands(noprompt, exitoneof)
  19:     bool noprompt, exitoneof;
  20: {
  21:     register line *addr;
  22:     register int c;
  23:     register int lchng;
  24:     int given;
  25:     int seensemi;
  26:     int cnt;
  27:     bool hadpr;
  28: 
  29:     resetflav();
  30:     nochng();
  31:     for (;;) {
  32:         /*
  33: 		 * If dot at last command
  34: 		 * ended up at zero, advance to one if there is a such.
  35: 		 */
  36:         if (dot <= zero) {
  37:             dot = zero;
  38:             if (dol > zero)
  39:                 dot = one;
  40:         }
  41:         shudclob = 0;
  42: 
  43:         /*
  44: 		 * If autoprint or trailing print flags,
  45: 		 * print the line at the specified offset
  46: 		 * before the next command.
  47: 		 */
  48:         if (pflag ||
  49:             lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline) {
  50:             pflag = 0;
  51:             nochng();
  52:             if (dol != zero) {
  53:                 addr1 = addr2 = dot + poffset;
  54:                 if (addr1 < one || addr1 > dol)
  55: error("Offset out-of-bounds|Offset after command too large");
  56:                 setdot1();
  57:                 goto print;
  58:             }
  59:         }
  60:         nochng();
  61: 
  62:         /*
  63: 		 * Print prompt if appropriate.
  64: 		 * If not in global flush output first to prevent
  65: 		 * going into pfast mode unreasonably.
  66: 		 */
  67:         if (inglobal == 0) {
  68:             flush();
  69:             if (!hush && value(PROMPT) && !globp && !noprompt && endline) {
  70:                 putchar(':');
  71:                 hadpr = 1;
  72:             }
  73:             TSYNC();
  74:         }
  75: 
  76:         /*
  77: 		 * Gobble up the address.
  78: 		 * Degenerate addresses yield ".".
  79: 		 */
  80:         addr2 = 0;
  81:         given = seensemi = 0;
  82:         do {
  83:             addr1 = addr2;
  84:             addr = address(0);
  85:             c = getcd();
  86:             if (addr == 0)
  87:                 if (c == ',')
  88:                     addr = dot;
  89:                 else if (addr1 != 0) {
  90:                     addr2 = dot;
  91:                     break;
  92:                 } else
  93:                     break;
  94:             addr2 = addr;
  95:             given++;
  96:             if (c == ';') {
  97:                 c = ',';
  98:                 dot = addr;
  99:                 seensemi = 1;
 100:             }
 101:         } while (c == ',');
 102:         if (c == '%') {
 103:             /* %: same as 1,$ */
 104:             addr1 = one;
 105:             addr2 = dol;
 106:             given = 2;
 107:             c = getchar();
 108:         }
 109:         if (addr1 == 0)
 110:             addr1 = addr2;
 111:         if (c == ':')
 112:             c = getchar();
 113: 
 114:         /*
 115: 		 * Set command name for special character commands.
 116: 		 */
 117:         tailspec(c);
 118: 
 119:         /*
 120: 		 * If called via : escape from open or visual, limit
 121: 		 * the set of available commands here to save work below.
 122: 		 */
 123:         if (inopen) {
 124:             if (c=='\n' || c=='\r' || c==CTRL(d) || c==EOF) {
 125:                 if (addr2)
 126:                     dot = addr2;
 127:                 if (c == EOF)
 128:                     return;
 129:                 continue;
 130:             }
 131:             if (any(c, "o"))
 132: notinvis:
 133:                 tailprim(Command, 1, 1);
 134:         }
 135: choice:
 136:         switch (c) {
 137: 
 138:         case 'a':
 139: 
 140:             if (peekchar() == 'r') {
 141: /* args */
 142:                 tail("args");
 143:                 setnoaddr();
 144:                 eol();
 145:                 pargs();
 146:                 continue;
 147:             }
 148: 
 149: /* append */
 150:             if (inopen)
 151:                 goto notinvis;
 152:             tail("append");
 153:             setdot();
 154:             aiflag = exclam();
 155:             newline();
 156:             deletenone();
 157:             setin(addr2);
 158:             ignore(append(gettty, addr2));
 159:             nochng();
 160:             continue;
 161: 
 162:         case 'c':
 163:             switch (peekchar()) {
 164: 
 165: /* copy */
 166:             case 'o':
 167:                 tail("copy");
 168:                 move();
 169:                 continue;
 170: 
 171: #ifdef CHDIR
 172: /* cd */
 173:             case 'd':
 174:                 tail("cd");
 175:                 goto changdir;
 176: 
 177: /* chdir */
 178:             case 'h':
 179:                 ignchar();
 180:                 if (peekchar() == 'd') {
 181:                     register char *p;
 182:                     tail2of("chdir");
 183: changdir:
 184:                     if (savedfile[0] == '/' || !value(WARN))
 185:                         ignore(exclam());
 186:                     else
 187:                         ignore(quickly());
 188:                     if (skipend()) {
 189:                         p = getenv("HOME");
 190:                         if (p == NULL)
 191:                             error("Home directory unknown");
 192:                     } else
 193:                         getone(), p = file;
 194:                     eol();
 195:                     if (chdir(p) < 0)
 196:                         filioerr(p);
 197:                     if (savedfile[0] != '/')
 198:                         edited = 0;
 199:                     continue;
 200:                 }
 201:                 if (inopen)
 202:                     tailprim("change", 2, 1);
 203:                 tail2of("change");
 204:                 break;
 205: 
 206: #endif
 207:             default:
 208:                 if (inopen)
 209:                     goto notinvis;
 210:                 tail("change");
 211:                 break;
 212:             }
 213: /* change */
 214:             aiflag = exclam();
 215:             setCNL();
 216:             setin(addr1);
 217:             delete(0);
 218:             ignore(append(gettty, addr1 - 1));
 219:             nochng();
 220:             continue;
 221: 
 222: /* delete */
 223:         case 'd':
 224:             /*
 225: 			 * Caution: dp and dl have special meaning already.
 226: 			 */
 227:             tail("delete");
 228:             c = cmdreg();
 229:             setCNL();
 230:             if (c)
 231:                 YANKreg(c);
 232:             delete(0);
 233:             appendnone();
 234:             continue;
 235: 
 236: /* edit */
 237: /* ex */
 238:         case 'e':
 239:             tail(peekchar() == 'x' ? "ex" : "edit");
 240: editcmd:
 241:             if (!exclam() && chng)
 242:                 c = 'E';
 243:             filename(c);
 244:             if (c == 'E') {
 245:                 ungetchar(lastchar());
 246:                 ignore(quickly());
 247:             }
 248:             setnoaddr();
 249: doecmd:
 250:             init();
 251:             addr2 = zero;
 252:             laste++;
 253:             sync();
 254:             rop(c);
 255:             nochng();
 256:             continue;
 257: 
 258: /* file */
 259:         case 'f':
 260:             tail("file");
 261:             setnoaddr();
 262:             filename(c);
 263:             noonl();
 264:             synctmp();
 265:             continue;
 266: 
 267: /* global */
 268:         case 'g':
 269:             tail("global");
 270:             global(!exclam());
 271:             nochng();
 272:             continue;
 273: 
 274: /* insert */
 275:         case 'i':
 276:             if (inopen)
 277:                 goto notinvis;
 278:             tail("insert");
 279:             setdot();
 280:             nonzero();
 281:             aiflag = exclam();
 282:             newline();
 283:             deletenone();
 284:             setin(addr2);
 285:             ignore(append(gettty, addr2 - 1));
 286:             if (dot == zero && dol > zero)
 287:                 dot = one;
 288:             nochng();
 289:             continue;
 290: 
 291: /* join */
 292:         case 'j':
 293:             tail("join");
 294:             c = exclam();
 295:             setcount();
 296:             nonzero();
 297:             newline();
 298:             if (given < 2 && addr2 != dol)
 299:                 addr2++;
 300:             join(c);
 301:             continue;
 302: 
 303: /* k */
 304:         case 'k':
 305: casek:
 306:             pastwh();
 307:             c = getchar();
 308:             if (endcmd(c))
 309:                 serror("Mark what?|%s requires following letter", Command);
 310:             newline();
 311:             if (!islower(c))
 312:                 error("Bad mark|Mark must specify a letter");
 313:             setdot();
 314:             nonzero();
 315:             names[c - 'a'] = *addr2 &~ 01;
 316:             anymarks = 1;
 317:             continue;
 318: 
 319: /* list */
 320:         case 'l':
 321:             tail("list");
 322:             setCNL();
 323:             ignorf(setlist(1));
 324:             pflag = 0;
 325:             goto print;
 326: 
 327:         case 'm':
 328:             if (peekchar() == 'a') {
 329: /* mark */
 330:                 tail("mark");
 331:                 goto casek;
 332:             }
 333: /* move */
 334:             tail("move");
 335:             move();
 336:             continue;
 337: 
 338:         case 'n':
 339:             if (peekchar() == 'u') {
 340:                 tail("number");
 341:                 goto numberit;
 342:             }
 343: /* next */
 344:             tail("next");
 345:             setnoaddr();
 346:             ckaw();
 347:             ignore(quickly());
 348:             if (getargs())
 349:                 makargs();
 350:             next();
 351:             c = 'e';
 352:             filename(c);
 353:             goto doecmd;
 354: 
 355: /* open */
 356:         case 'o':
 357:             tail("open");
 358:             oop();
 359:             pflag = 0;
 360:             nochng();
 361:             continue;
 362: 
 363:         case 'p':
 364:         case 'P':
 365:             switch (peekchar()) {
 366: 
 367: /* put */
 368:             case 'u':
 369:                 tail("put");
 370:                 setdot();
 371:                 c = cmdreg();
 372:                 eol();
 373:                 if (c)
 374:                     putreg(c);
 375:                 else
 376:                     put();
 377:                 continue;
 378: 
 379:             case 'r':
 380:                 ignchar();
 381:                 if (peekchar() == 'e') {
 382: /* preserve */
 383:                     tail2of("preserve");
 384:                     eol();
 385:                     if (preserve() == 0)
 386:                         error("Preserve failed!");
 387:                     else
 388:                         error("File preserved.");
 389:                 }
 390:                 tail2of("print");
 391:                 break;
 392: 
 393:             default:
 394:                 tail("print");
 395:                 break;
 396:             }
 397: /* print */
 398:             setCNL();
 399:             pflag = 0;
 400: print:
 401:             nonzero();
 402:             if (CL && span() > LINES) {
 403:                 flush1();
 404:                 vclear();
 405:             }
 406:             plines(addr1, addr2, 1);
 407:             continue;
 408: 
 409: /* quit */
 410:         case 'q':
 411:             tail("quit");
 412:             setnoaddr();
 413:             c = quickly();
 414:             eol();
 415:             if (!c)
 416: quit:
 417:                 nomore();
 418:             if (inopen) {
 419:                 vgoto(WECHO, 0);
 420:                 if (!ateopr())
 421:                     vnfl();
 422:                 else
 423:                     putpad(VE);
 424:                 flush();
 425:                 setty(normf);
 426:             }
 427:             cleanup(1);
 428:             exit(0);
 429: 
 430:         case 'r':
 431:             if (peekchar() == 'e') {
 432:                 ignchar();
 433:                 switch (peekchar()) {
 434: 
 435: /* rewind */
 436:                 case 'w':
 437:                     tail2of("rewind");
 438:                     setnoaddr();
 439:                     eol();
 440:                     ckaw();
 441:                     ignore(quickly());
 442:                     erewind();
 443:                     next();
 444:                     c = 'e';
 445:                     ungetchar(lastchar());
 446:                     filename(c);
 447:                     goto doecmd;
 448: 
 449: /* recover */
 450:                 case 'c':
 451:                     tail2of("recover");
 452:                     setnoaddr();
 453:                     c = 'e';
 454:                     if (!exclam() && chng)
 455:                         c = 'E';
 456:                     filename(c);
 457:                     if (c == 'E') {
 458:                         ungetchar(lastchar());
 459:                         ignore(quickly());
 460:                     }
 461:                     init();
 462:                     addr2 = zero;
 463:                     laste++;
 464:                     sync();
 465:                     recover();
 466:                     rop2();
 467:                     revocer();
 468:                     if (status == 0)
 469:                         rop3(c);
 470:                     if (dol != zero)
 471:                         change();
 472:                     nochng();
 473:                     continue;
 474:                 }
 475:                 tail2of("read");
 476:             } else
 477:                 tail("read");
 478: /* read */
 479:             if (savedfile[0] == 0 && dol == zero)
 480:                 c = 'e';
 481:             pastwh();
 482:             if (peekchar() == '!') {
 483:                 setdot();
 484:                 ignchar();
 485:                 unix0(0);
 486:                 filter(0);
 487:                 continue;
 488:             }
 489:             filename(c);
 490:             rop(c);
 491:             nochng();
 492:             if (inopen && endline && addr1 > zero && addr1 < dol)
 493:                 dot = addr1 + 1;
 494:             continue;
 495: 
 496:         case 's':
 497:             switch (peekchar()) {
 498: 
 499: /* set */
 500:             case 'e':
 501:                 tail("set");
 502:                 setnoaddr();
 503:                 set();
 504:                 continue;
 505: 
 506: /* shell */
 507:             case 'h':
 508:                 tail("shell");
 509:                 setNAEOL();
 510:                 vnfl();
 511:                 putpad(TE);
 512:                 flush();
 513:                 unixwt(1, unixex("-i", (char *) 0, 0, 0));
 514:                 vcontin(0);
 515:                 putpad(TI);
 516:                 continue;
 517: 
 518: /* source */
 519:             case 'o':
 520:                 if (inopen)
 521:                     goto notinvis;
 522:                 tail("source");
 523:                 setnoaddr();
 524:                 getone();
 525:                 eol();
 526:                 source(file, 0);
 527:                 continue;
 528:             }
 529:             /* fall into ... */
 530: 
 531: /* & */
 532: /* ~ */
 533: /* substitute */
 534:         case '&':
 535:         case '~':
 536:             Command = "substitute";
 537:             if (c == 's')
 538:                 tail(Command);
 539:             if (!substitute(c))
 540:                 pflag = 0;
 541:             continue;
 542: 
 543: /* t */
 544:         case 't':
 545: #ifdef TAGSCODE
 546:             if (peekchar() == 'a') {
 547:                 tail("tag");
 548:                 tagfind(exclam());
 549:                 if (!inopen)
 550:                     lchng = chng - 1;
 551:                 else
 552:                     nochng();
 553:                 continue;
 554:             }
 555: #endif
 556:             tail("t");
 557:             move();
 558:             continue;
 559: 
 560: /* undo */
 561:         case 'u':
 562:             tail("undo");
 563:             setnoaddr();
 564:             markDOT();
 565:             c = exclam();
 566:             newline();
 567:             undo(c);
 568:             continue;
 569: 
 570:         case 'v':
 571:             switch (peekchar()) {
 572: 
 573:             case 'e':
 574: /* version */
 575:                 tail("version");
 576:                 setNAEOL();
 577:                 printf("Version 2.13, 9/5/80");
 578:                 noonl();
 579:                 continue;
 580: 
 581: /* visual */
 582:             case 'i':
 583:                 tail("visual");
 584:                 if (inopen) {
 585:                     c = 'e';
 586:                     goto editcmd;
 587:                 }
 588:                 vop();
 589:                 pflag = 0;
 590:                 nochng();
 591:                 continue;
 592:             }
 593: /* v */
 594:             tail("v");
 595:             global(0);
 596:             nochng();
 597:             continue;
 598: 
 599: /* write */
 600:         case 'w':
 601:             c = peekchar();
 602:             tail(c == 'q' ? "wq" : "write");
 603: wq:
 604:             if (skipwh() && peekchar() == '!') {
 605:                 ignchar();
 606:                 setall();
 607:                 unix0(0);
 608:                 filter(1);
 609:             } else {
 610:                 setall();
 611:                 wop(1);
 612:                 nochng();
 613:             }
 614:             if (c == 'q')
 615:                 goto quit;
 616:             continue;
 617: 
 618: /* xit */
 619:         case 'x':
 620:             tail("xit");
 621:             if (!chng)
 622:                 goto quit;
 623:             c = 'q';
 624:             goto wq;
 625: 
 626: /* yank */
 627:         case 'y':
 628:             tail("yank");
 629:             c = cmdreg();
 630:             setcount();
 631:             eol();
 632:             if (c)
 633:                 YANKreg(c);
 634:             else
 635:                 yank();
 636:             continue;
 637: 
 638: /* z */
 639:         case 'z':
 640:             zop(0);
 641:             pflag = 0;
 642:             continue;
 643: 
 644: /* | */
 645:         case '|':
 646:             endline = 0;
 647:             goto caseline;
 648: 
 649: /* \n */
 650:         case '\n':
 651:             endline = 1;
 652: caseline:
 653:             notempty();
 654:             if (addr2 == 0) {
 655:                 if (UP != NOSTR && c == '\n' && !inglobal)
 656:                     c = CTRL(k);
 657:                 if (inglobal)
 658:                     addr1 = addr2 = dot;
 659:                 else {
 660:                     if (dot == dol)
 661:                         error("At EOF|At end-of-file");
 662:                     addr1 = addr2 = dot + 1;
 663:                 }
 664:             }
 665:             setdot();
 666:             nonzero();
 667:             if (seensemi)
 668:                 addr1 = addr2;
 669:             getline(*addr1);
 670:             if (c == CTRL(k)) {
 671:                 flush1();
 672:                 destline--;
 673:                 if (hadpr)
 674:                     shudclob = 1;
 675:             }
 676:             plines(addr1, addr2, 1);
 677:             continue;
 678: 
 679: /* " */
 680:         case '"':
 681:             comment();
 682:             continue;
 683: 
 684: /* # */
 685:         case '#':
 686: numberit:
 687:             setCNL();
 688:             ignorf(setnumb(1));
 689:             pflag = 0;
 690:             goto print;
 691: 
 692: /* = */
 693:         case '=':
 694:             newline();
 695:             setall();
 696:             printf("%d", lineno(addr2));
 697:             noonl();
 698:             continue;
 699: 
 700: /* ! */
 701:         case '!':
 702:             if (addr2 != 0) {
 703:                 unix0(0);
 704:                 setdot();
 705:                 filter(2);
 706:             } else {
 707:                 unix0(1);
 708:                 vnfl();
 709:                 putpad(TE);
 710:                 flush();
 711:                 unixwt(1, unixex("-c", uxb, 0, 0));
 712:                 vcontin(1);
 713:                 putpad(TI);
 714:                 nochng();
 715:             }
 716:             continue;
 717: 
 718: /* < */
 719: /* > */
 720:         case '<':
 721:         case '>':
 722:             for (cnt = 1; peekchar() == c; cnt++)
 723:                 ignchar();
 724:             setCNL();
 725:             shift(c, cnt);
 726:             continue;
 727: 
 728: /* ^D */
 729: /* EOF */
 730:         case CTRL(d):
 731:         case EOF:
 732:             if (exitoneof) {
 733:                 if (addr2 != 0)
 734:                     dot = addr2;
 735:                 return;
 736:             }
 737:             if (!isatty(0)) {
 738:                 if (intty)
 739:                     /*
 740: 					 * Chtty sys call at UCB may cause a
 741: 					 * input which was a tty to suddenly be
 742: 					 * turned into /dev/null.
 743: 					 */
 744:                     onhup();
 745:                 return;
 746:             }
 747:             if (addr2 != 0) {
 748:                 setlastchar('\n');
 749:                 putnl();
 750:             }
 751:             if (dol == zero) {
 752:                 if (addr2 == 0)
 753:                     putnl();
 754:                 notempty();
 755:             }
 756:             ungetchar(EOF);
 757:             zop(hadpr);
 758:             continue;
 759: 
 760:         default:
 761:             if (!isalpha(c))
 762:                 break;
 763:             ungetchar(c);
 764:             tailprim("", 0, 0);
 765:         }
 766:         error("What?|Unknown command character '%c'", c);
 767:     }
 768: }

Defined functions

Defined variables

nflag defined in line 7; never used
pflag defined in line 7; used 9 times
poffset defined in line 8; used 1 times
  • in line 53

Defined macros

nochng defined in line 10; used 16 times
Last modified: 1980-09-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1868
Valid CSS Valid XHTML 1.0 Strict