home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / ex / ex_cmds.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  11KB  |  717 lines

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