home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 100-199 / ff153.lzh / Dme / src / cmd1.c next >
C/C++ Source or Header  |  1987-06-15  |  18KB  |  998 lines

  1.  
  2.  
  3. /*
  4.  * CMD1.C   (was TEXT1.C)
  5.  *
  6.  *    (C)Copyright 1987 by Matthew Dillon,    All Rights Reserved
  7.  */
  8.  
  9. #include "defs.h"
  10.  
  11. #define nomemory()  { memoryfail = 1; }
  12.  
  13. char RecallBuf[256];
  14.  
  15. setpen(line)
  16. {
  17.     register short pen = (Ep == BEp && line >= BSline && line <= BEline) ? 2 : 1;
  18.     if (Comlinemode)
  19.     pen = 1;
  20.     if (pen != Rp->FgPen)
  21.     SetAPen(Rp, pen);
  22. }
  23.  
  24. text_init()
  25. {
  26.     register ED *e;
  27.     register ED *ep = Ep;
  28.  
  29.     text_switch(NULL);
  30.     e = (ED *)allocb(sizeof(ED));
  31.     if (e == NULL)
  32.     return(0);
  33.     bzero(e, sizeof(ED));
  34.     e->Win = Win;
  35.     if (ep) {
  36.     e->Insertmode = ep->Insertmode;
  37.     e->IgnoreCase = ep->IgnoreCase;
  38.     e->Tabstop    = ep->Tabstop;
  39.     e->Wordwrap   = ep->Wordwrap;
  40.     if (ep->Font) {
  41.         e->Font = ep->Font;
  42.         ++e->Font->tf_Accessors;
  43.         SetFont(Win->RPort, e->Font);
  44.     }
  45.     } else {
  46.     e->Insertmode = 1;
  47.     e->Tabstop = 4;
  48.     }
  49.     e->Lines = 1;
  50.     e->Maxlines = 32;
  51.     e->List = (ubyte **)allocl(e->Maxlines);
  52.     e->List[0] = allocb(1);
  53.     e->List[0][0] = Current[0] = Clen = 0;
  54.     e->IWiny = 16;
  55.     e->dirlock = (ep) ? ep->dirlock : Dirlock;
  56.     llink(&Base, e);
  57.     strcpy(e->Name, "unnamed");
  58.     Ep = e;
  59.     text_cursor(1);
  60.     return(1);
  61. }
  62.  
  63.  
  64. text_switch(win)
  65. WIN *win;
  66. {
  67.     register ED *e;
  68.  
  69.     if (win)
  70.     text_sync();
  71.     if (win) {
  72.     for (e = Base; e; e = e->next) {
  73.         if (e->Win == win) {
  74.         Ep = e;
  75.         Win = win;
  76.         Rp = Win->RPort;
  77.         text_load();
  78.         if (!Ep->iconmode) {
  79.             set_window_params();
  80.             window_title();
  81.         }
  82.         return(1);
  83.         }
  84.     }
  85.     return(0);
  86.     }
  87. }
  88.  
  89.  
  90. text_sync()
  91. {
  92.     register ED *ep = Ep;
  93.     char redraw = 0;
  94.     short len;
  95.     ubyte *ptr;
  96.  
  97.     for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
  98.     Current[len] = '\0';
  99.     Clen = len + 1;
  100.     if (!Comlinemode) {
  101.     if (strlen(ep->List[ep->Line]) != Clen) {
  102.         if (ptr = allocb(Clen+1)) {
  103.         ep->Modified = 1;
  104.         Overide = 0;
  105.         FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
  106.         ep->List[ep->Line] = ptr;
  107.         } else {
  108.         nomemory();
  109.         strcpy(Current, ep->List[ep->Line]);
  110.         Clen = strlen(Current);
  111.         }
  112.     } else {
  113.         if (strcmp(ep->List[ep->Line], Current)) {
  114.         ep->Modified = 1;
  115.         Overide = 0;
  116.         }
  117.     }
  118.     strcpy(ep->List[ep->Line], Current);
  119.     }
  120.     if (Nsu == 0) {
  121.     if (ep->Column - ep->Topcolumn >= Columns || ep->Column < ep->Topcolumn) {
  122.         redraw = 1;
  123.         ep->Topcolumn = ep->Column - (Columns>>1);
  124.         if (ep->Topcolumn < 0)
  125.         ep->Topcolumn = 0;
  126.     }
  127.     if (ep->Line - ep->Topline >= Rows || ep->Line < ep->Topline) {
  128.         redraw = 1;
  129.         ep->Topline = ep->Line - (Rows>>1);
  130.         if (ep->Topline < 0)
  131.         ep->Topline = 0;
  132.     }
  133.     }
  134.     while (ep->Column > Clen)
  135.     Current[Clen++] = ' ';
  136.     Current[Clen] = '\0';
  137.     if (redraw)
  138.     text_redisplay();
  139.     return((int)redraw);
  140. }
  141.  
  142. text_load()
  143. {
  144.     if (Comlinemode)
  145.     return(0);
  146.     strcpy(Current, Ep->List[Ep->Line]);
  147.     Clen = strlen(Current);
  148.     while (Ep->Column > Clen)
  149.     Current[Clen++] = ' ';
  150.     Current[Clen] = '\0';
  151. }
  152.  
  153. text_colno()
  154. {
  155.     return(Ep->Column);
  156. }
  157.  
  158. text_lineno()
  159. {
  160.     return(Ep->Line+1);
  161. }
  162.  
  163. text_lines()
  164. {
  165.     return(Ep->Lines);
  166. }
  167.  
  168. text_cols()
  169. {
  170.     return((int)Clen);
  171. }
  172.  
  173. text_imode()
  174. {
  175.     return(Ep->Insertmode);
  176. }
  177.  
  178. text_tabsize()
  179. {
  180.     return((int)Ep->Tabstop);
  181. }
  182.  
  183. ubyte *
  184. text_name()
  185. {
  186.     return(Ep->Name);
  187. }
  188.  
  189. text_uninit()
  190. {
  191.     register int i;
  192.     register ED *ep = Ep;
  193.  
  194.     PMKill(ep);
  195.     freelist(ep->List, ep->Lines);
  196.     FreeMem(ep->List, ep->Maxlines * sizeof(char *));
  197.  
  198.     if (BEp == ep) {
  199.     BEp = NULL;
  200.     BSline = BEline = -1;
  201.     }
  202.     lunlink(ep);
  203.     if (ep->Font) {
  204.     SetFont(ep->Win->RPort, ep->Win->WScreen->RastPort.Font);
  205.     CloseFont(ep->Font);
  206.     }
  207.     FreeMem(ep, sizeof(ED));
  208.     if (Base) {
  209.     Ep = Base;
  210.     text_load();
  211.     } else {
  212.     Ep = NULL;
  213.     }
  214. }
  215.  
  216. inversemode(n)
  217. {
  218.     if (n) {
  219.     SetAPen(Rp, 3);
  220.     SetDrMd(Rp, JAM2|INVERSVID);
  221.     } else {
  222.     setpen(Ep->Line);
  223.     SetDrMd(Rp, JAM2);
  224.     }
  225. }
  226.  
  227. text_cursor(n)
  228. {
  229.     movetocursor();
  230.     inversemode(n);
  231.     if (Current[Ep->Column])
  232.     Text(Rp, Current+Ep->Column, 1);
  233.     else
  234.     Text(Rp, " ", 1);
  235.     inversemode(0);
  236. }
  237.  
  238.  
  239. text_position(col, row)
  240. {
  241.     register ED *ep = Ep;
  242.     text_sync();
  243.     if (col == 0)
  244.     col = -1;
  245.     ep->Column = ep->Topcolumn + col;
  246.     if (ep->Column > 254)
  247.     ep->Column = 254;
  248.     if (ep->Column < 0)
  249.     ep->Column = 0;
  250.     ep->Line = ep->Topline + row;
  251.     if (ep->Line >= ep->Lines)
  252.     ep->Line = ep->Lines - 1;
  253.     if (ep->Line < 0)
  254.     ep->Line = 0;
  255.     text_load();
  256.     text_sync();
  257. }
  258.  
  259. displayblock(on)
  260. {
  261.     register long start = Ep->Topline;
  262.     register long lines = BEline - BSline + 1;
  263.  
  264.     if (start < BSline)
  265.     start = BSline;
  266.     if (!on) {
  267.     BSline = BEline = -1;
  268.     BEp = NULL;
  269.     }
  270.     if (Ep == BEp)
  271.     text_displayseg(start - Ep->Topline, lines);
  272. }
  273.  
  274. text_redrawblock(ok)
  275. {
  276.     WIN *savewin = NULL;
  277.  
  278.     if (BEp) {
  279.     if (BEp != Ep) {
  280.         savewin = Ep->Win;
  281.         text_switch(BEp->Win);
  282.     }
  283.     if (BSline <= BEline && BSline >= 0 && BEline < Ep->Lines) {
  284.         if (!ok) {
  285.         BEp = NULL;
  286.         BSline = BEline = -1;
  287.         }
  288.         text_displayseg(0, Rows);
  289.     }
  290.     if (savewin)
  291.         text_switch(savewin);
  292.     }
  293.     if (!ok) {
  294.     BEp = NULL;
  295.     BSline = BEline = -1;
  296.     }
  297. }
  298.  
  299. text_displayseg(start, n)
  300. {
  301.     register short i, c;
  302.     register ubyte *ptr;
  303.     register ED *ep = Ep;
  304.     char ib;
  305.  
  306.     if (Nsu)
  307.     return(0);
  308.     for (i = start; i < start + n && i < Rows && ep->Topline + i < ep->Lines; ++i) {
  309.     if (Comlinemode) {
  310.         if (ep->Topline + i != ep->Line)
  311.         continue;
  312.         ptr = Current;
  313.         SetAPen(Rp, 1);
  314.     } else {
  315.         ptr = ep->List[ep->Topline + i];
  316.         setpen(i+ep->Topline);
  317.     }
  318.     for (c = ep->Topcolumn; c && *ptr; ++ptr, --c);
  319.     c = strlen(ptr);
  320.     if (c) {
  321.         Move(Rp, COLT(0), ROWT(i));
  322.         Text(Rp, ptr, (c > Columns) ? Columns : c);
  323.     }
  324.     }
  325. }
  326.  
  327. text_redisplay()
  328. {
  329.     if (Nsu)
  330.     return(0);
  331.     SetAPen(Rp, 0);
  332.     if (Comlinemode)
  333.     RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
  334.     else
  335.     RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs);
  336.     text_displayseg(0,Rows);
  337. }
  338.  
  339. text_redisplaycurrline()
  340. {
  341.     int row = Ep->Line - Ep->Topline;
  342.  
  343.     if (Nsu)
  344.     return(0);
  345.     SetAPen(Rp, 0);
  346.     RectFill(Rp, COL(0), ROW(row), Xbase+Xpixs, ROW(row+1)-1);
  347.     text_displayseg(row, 1);
  348. }
  349.  
  350. text_write(str)
  351. ubyte *str;
  352. {
  353.     register short len = strlen(str);
  354.     register short i;
  355.     register ED *ep = Ep;
  356.  
  357.     if (Clen + len >= 255) {
  358.     text_sync();
  359.     text_load();
  360.     }
  361.     if (ep->Insertmode == 0) {
  362.     if (ep->Column + len >= 255)
  363.         goto fail;
  364.     bmov(str, Current + ep->Column, len);
  365.     if (ep->Column + len >= Clen)
  366.         Clen = ep->Column + len;
  367.     Current[Clen] = 0;
  368.     } else {
  369.     if (Clen + len >= 255)
  370.         goto fail;
  371.     bmov(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column);
  372.     bmov(str, Current + ep->Column, len);
  373.     Clen += len;
  374.     if (len < Columns - (ep->Column - ep->Topcolumn)) {
  375.         ScrollRaster(Rp, -len * Xsize, 0 ,
  376.         COL(ep->Column - ep->Topcolumn),
  377.         ROW(ep->Line - ep->Topline),
  378.         COL(Columns) - 1,
  379.         ROW(ep->Line - ep->Topline + 1) - 1
  380.         );
  381.     }
  382.     }
  383.     i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len;
  384.     setpen(ep->Line);
  385.     Move(Rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline));
  386.     Text(Rp, str, i);
  387.     ep->Column += len;
  388.     if (ep->Column - ep->Topcolumn >= Columns)
  389.     text_sync();
  390. fail:
  391.     if (Comlinemode == 0 && ep->Wordwrap)
  392.     do_reformat(0);
  393. }
  394.  
  395.  
  396. do_up()
  397. {
  398.     if (Ep->Line) {
  399.     text_sync();
  400.     --Ep->Line;
  401.     text_load();
  402.     if (Ep->Line < Ep->Topline) {
  403.         if (Nsu == 0) {
  404.         ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  405.         --Ep->Topline;
  406.         text_displayseg(0, 1);
  407.         }
  408.     }
  409.     } else {
  410.     Abortcommand = 1;
  411.     }
  412. }
  413.  
  414. do_scrolldown()
  415. {
  416.     if (Ep->Topline + Rows < Ep->Lines) {
  417.     if (Nsu == 0) {
  418.         text_sync();
  419.         ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  420.         ++Ep->Topline;
  421.         ++Ep->Line;
  422.         text_load();
  423.         text_displayseg(Rows-1, 1);
  424.     }
  425.     } else {
  426.     Abortcommand = 1;
  427.     }
  428. }
  429.  
  430. do_scrollup()
  431. {
  432.     if (Ep->Topline) {
  433.     if (Nsu == 0) {
  434.         text_sync();
  435.         ScrollRaster(Rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  436.         --Ep->Topline;
  437.         --Ep->Line;
  438.         text_load();
  439.         text_displayseg(0, 1);
  440.     }
  441.     } else {
  442.     Abortcommand = 1;
  443.     }
  444. }
  445.  
  446. do_down()
  447. {
  448.     if (Ep->Line + 1 < Ep->Lines) {
  449.     text_sync();
  450.     ++Ep->Line;
  451.     text_load();
  452.     if (Ep->Line - Ep->Topline >= Rows) {
  453.         if (Nsu == 0) {
  454.         ScrollRaster(Rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  455.         ++Ep->Topline;
  456.         text_displayseg(Rows-1, 1);
  457.         }
  458.     }
  459.     } else {
  460.     Abortcommand = 1;
  461.     }
  462. }
  463.  
  464. /*
  465.  *  PAGEUP
  466.  *  PAGEDOWN
  467.  *  PAGESET n    (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
  468.  *        can be > 100.
  469.  */
  470.  
  471. do_page()
  472. {
  473.     register int n, multiplier = 1;
  474.     register ED *ep = Ep;
  475.     static short pctg = 80;
  476.  
  477.     switch(av[0][4]) {
  478.     case 'u':
  479.     multiplier = -1;
  480.     case 'd':
  481.     n = multiplier * Rows * pctg / 100;
  482.     if (!n)
  483.         n = multiplier;
  484.     if (n > 0 && ep->Topline >= ep->Lines - Rows)
  485.         return(0);
  486.     text_sync();
  487.     ep->Line += n;
  488.     ep->Topline += n;
  489.     if (ep->Line >= ep->Lines)
  490.         ep->Line = ep->Lines - 1;
  491.     if (ep->Line < 0)
  492.         ep->Line = 0;
  493.     if (ep->Topline >= ep->Lines)
  494.         ep->Topline = ep->Lines - Rows - 1;
  495.     if (ep->Topline < 0)
  496.         ep->Topline = 0;
  497.     text_load();
  498.     if (!text_sync())
  499.         text_redisplay();
  500.     break;
  501.     case 's':
  502.     pctg = atoi(av[1]);
  503.     break;
  504.     }
  505. }
  506.  
  507.  
  508. do_downadd()
  509. {
  510.     ubyte *ptr;
  511.  
  512.     if (Ep->Line + 1 == Ep->Lines) {
  513.     Ep->Modified = 1;
  514.     if (makeroom(32) && (ptr = allocb(1))) {
  515.         Ep->List[Ep->Lines] = ptr;
  516.         *ptr = 0;
  517.         ++Ep->Lines;
  518.     } else {
  519.         nomemory();
  520.     }
  521.     }
  522.     do_down();
  523. }
  524.  
  525.  
  526. do_left()
  527. {
  528.     if (Ep->Column) {
  529.     --Ep->Column;
  530.     if (Ep->Column < Ep->Topcolumn)
  531.         text_sync();
  532.     } else {
  533.     Abortcommand = 1;
  534.     }
  535. }
  536.  
  537. do_right()
  538. {
  539.     if (Ep->Column != 254) {
  540.     if (Current[Ep->Column] == 0) {
  541.         Current[Ep->Column] = ' ';
  542.         Current[Ep->Column+1]= '\0';
  543.         ++Clen;
  544.     }
  545.     ++Ep->Column;
  546.     if (Ep->Column - Ep->Topcolumn >= Columns)
  547.         text_sync();
  548.     } else {
  549.     Abortcommand = 1;
  550.     }
  551. }
  552.  
  553. do_tab()
  554. {
  555.     register short n;
  556.  
  557.     for (n = Ep->Tabstop-(Ep->Column % Ep->Tabstop); n > 0; --n)
  558.     do_right();
  559. }
  560.  
  561. do_backtab()
  562. {
  563.     register short n;
  564.  
  565.     n = Ep->Column % Ep->Tabstop;
  566.     if (!n)
  567.     n = Ep->Tabstop;
  568.     for (; n > 0; --n)
  569.     do_left();
  570. }
  571.  
  572. do_return()
  573. {
  574.     ubyte buf[256];
  575.     char *partial;
  576.  
  577.     if (Comlinemode) {
  578.     strcpy(buf, Current);
  579.     strcpy(RecallBuf, Current);
  580.     partial = Partial;
  581.     Partial = NULL;
  582.     escapecomlinemode();
  583.     if (partial) {
  584.         if (do_command(buf))
  585.         do_command(partial);
  586.         free(partial);
  587.     } else {
  588.         do_command(buf);
  589.     }
  590.     } else {
  591.     Ep->Column = 0;
  592.     text_sync();
  593.     do_downadd();
  594.     }
  595. }
  596.  
  597. do_bs()
  598. {
  599.     register ED *ep = Ep;
  600.     if (ep->Column) {
  601.     bmov(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1);
  602.     --ep->Column;
  603.     --Clen;
  604.     if (ep->Column < ep->Topcolumn) {
  605.         text_sync();
  606.     } else {
  607.         ScrollRaster(Rp, Xsize, 0,
  608.         COL(ep->Column - ep->Topcolumn),
  609.         ROW(ep->Line   - ep->Topline),
  610.         COL(Columns)-1,
  611.         ROW(ep->Line - ep->Topline + 1)-1
  612.         );
  613.         if (Clen >= ep->Topcolumn + Columns) {
  614.         setpen(ep->Line);
  615.         Move(Rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline));
  616.         Text(Rp, Current + ep->Topcolumn + Columns - 1, 1);
  617.         }
  618.     }
  619.     if (Comlinemode == 0 && ep->Wordwrap)
  620.         do_reformat(0);
  621.     } else {
  622.     Abortcommand = 1;
  623.     }
  624. }
  625.  
  626.  
  627. /*
  628.  * esc, escimm
  629.  */
  630.  
  631. int Savetopline, Savecolumn, Savetopcolumn;
  632.  
  633. do_recall()
  634. {
  635.     av[0] = (ubyte *)"escimm";
  636.     av[1] = (ubyte *)RecallBuf;
  637.     do_esc();
  638. }
  639.  
  640. do_esc()
  641. {
  642.     register ED *ep = Ep;
  643.  
  644.     if (Comlinemode)
  645.     return(escapecomlinemode());
  646.     text_sync();
  647.     if (av[0][3] == 'i')
  648.     strcpy(Current, av[1]);
  649.     else
  650.     Current[0] = 0;
  651.     Clen = strlen(Current);
  652.     Comlinemode = 1;
  653.     returnoveride(1);
  654.     Savetopline = ep->Topline;
  655.     Savecolumn    = ep->Column;
  656.     Savetopcolumn = ep->Topcolumn;
  657.     ep->Column      = Clen;
  658.     ep->Topcolumn = 0;
  659.     ep->Topline   = ep->Line - Rows + 1;
  660.     SetAPen(Rp, 0);
  661.     RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
  662.     SetAPen(Rp, 1);
  663.     Move(Rp, COL(0), ROW(Rows-1) - 1);
  664.     Draw(Rp, Xbase + Xpixs, ROW(Rows-1) - 1);
  665.     text_displayseg(Rows-1,1);
  666. }
  667.  
  668.  
  669. escapecomlinemode()
  670. {
  671.     register ED *ep = Ep;
  672.  
  673.     if (Partial) {
  674.     free(Partial);
  675.     Partial = NULL;
  676.     }
  677.     if (Comlinemode) {
  678.     strcpy(RecallBuf, Current);
  679.     Comlinemode = 0;
  680.     returnoveride(0);
  681.     ep->Topline = Savetopline;
  682.     ep->Column  = Savecolumn;
  683.     ep->Topcolumn = Savetopcolumn;
  684.     text_load();
  685.     SetAPen(Rp, 0);
  686.     RectFill(Rp, COL(0), ROW(Rows-1)-1, Xbase+Xpixs, Ybase+Ypixs);
  687.     SetAPen(Rp, 1);
  688.     text_displayseg(Rows-2,2);
  689.     }
  690. }
  691.  
  692.  
  693. do_del()
  694. {
  695.     register ED *ep = Ep;
  696.  
  697.     if (Current[ep->Column]) {
  698.     bmov(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column);
  699.     --Clen;
  700.     ScrollRaster(Rp, Xsize, 0,
  701.         COL(ep->Column - ep->Topcolumn),
  702.         ROW(ep->Line - ep->Topline),
  703.         COL(Columns)-1,
  704.         ROW(ep->Line - ep->Topline + 1) - 1
  705.     );
  706.     if (Clen >= ep->Topcolumn + Columns) {
  707.         setpen(ep->Line);
  708.         Move(Rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline));
  709.         Text(Rp, Current+ep->Topcolumn+Columns-1, 1);
  710.     }
  711.     if (Comlinemode == 0 && ep->Wordwrap)
  712.         do_reformat(0);
  713.     }
  714. }
  715.  
  716. do_top()
  717. {
  718.     text_sync();
  719.     Ep->Line = 0;
  720.     text_load();
  721.     text_sync();
  722. }
  723.  
  724. do_bottom()
  725. {
  726.     text_sync();
  727.     Ep->Line = Ep->Lines - 1;
  728.     text_load();
  729.     text_sync();
  730. }
  731.  
  732. do_firstcolumn()
  733. {
  734.     if (Ep->Column) {
  735.     Ep->Column = 0;
  736.     text_sync();
  737.     }
  738. }
  739.  
  740. do_firstnb()
  741. {
  742.     for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column);
  743.     if (Current[Ep->Column] == 0)
  744.     Ep->Column = 0;
  745.     text_sync();
  746. }
  747.  
  748. do_lastcolumn()
  749. {
  750.     short i;
  751.  
  752.     text_sync();
  753.     i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]);
  754.     if (i != Ep->Column) {
  755.     Ep->Column = i;
  756.     text_sync();
  757.     }
  758. }
  759.  
  760. /*
  761.  * GOTO [+/-]N
  762.  * GOTO BLOCK    start of block
  763.  * GOTO START    start of block
  764.  * GOTO END    end of block
  765.  */
  766.  
  767. do_goto()
  768. {
  769.     register short n, i;
  770.     register ubyte *ptr = av[1];
  771.  
  772.     i = 0;
  773.     n = -1;
  774.  
  775.     switch(*ptr) {
  776.     case 'b':
  777.     case 's':
  778.     case 'B':
  779.     case 'S':
  780.     n = -1;
  781.     if (Ep == BEp)
  782.         n = BSline;
  783.     break;
  784.     case 'e':
  785.     case 'E':
  786.     n = -1;
  787.     if (Ep == BEp)
  788.         n = BEline;
  789.     break;
  790.     case '+':
  791.     i = 1;
  792.     case '-':
  793.     n = Ep->Line;
  794.     default:
  795.     n += atoi(ptr+i);
  796.     }
  797.     if (n >= Ep->Lines)
  798.     n = Ep->Lines - 1;
  799.     if (n < 0)
  800.     n = 0;
  801.     text_sync();
  802.     Ep->Line = n;
  803.     text_load();
  804.     text_sync();
  805. }
  806.  
  807. do_screentop()
  808. {
  809.     text_sync();
  810.     Ep->Line = Ep->Topline;
  811.     text_load();
  812.     text_sync();
  813. }
  814.  
  815. do_screenbottom()
  816. {
  817.     text_sync();
  818.     Ep->Line = Ep->Topline + Rows - 1;
  819.     if (Ep->Line < 0 || Ep->Line >= Ep->Lines)
  820.     Ep->Line = Ep->Lines - 1;
  821.     text_load();
  822.     text_sync();
  823. }
  824.  
  825. static ubyte Fstr[256];
  826. static ubyte Rstr[256];
  827. static short Srch_sign;
  828. static char Doreplace;
  829.  
  830. /*
  831.  * findstr, repstr
  832.  */
  833.  
  834. do_findstr()
  835. {
  836.     if (av[0][0] == 'f')
  837.     strcpy(Fstr, av[1]);
  838.     else
  839.     strcpy(Rstr, av[1]);
  840. }
  841.  
  842. /*
  843.  * findr, nextr, prevr
  844.  */
  845.  
  846. do_findr()
  847. {
  848.     Doreplace = 1;
  849.     Srch_sign = 1;
  850.     switch(av[0][0]) {
  851.     case 'f':
  852.     strcpy(Fstr, av[1]);
  853.     strcpy(Rstr, av[2]);
  854.     break;
  855.     case 'p':
  856.     Srch_sign = -1;
  857.     break;
  858.     }
  859.     search_operation();
  860. }
  861.  
  862. /*
  863.  * find, next, prev
  864.  */
  865.  
  866. do_find()
  867. {
  868.     Doreplace = 0;
  869.     Srch_sign = 1;
  870.     switch(av[0][0]) {
  871.     case 'f':
  872.     strcpy(Fstr, av[1]);
  873.     break;
  874.     case 'p':
  875.     Srch_sign = -1;
  876.     break;
  877.     }
  878.     search_operation();
  879. }
  880.  
  881.  
  882. static char CaseIgnore;
  883.  
  884. void
  885. search_operation()
  886. {
  887.     int flen = strlen(Fstr);
  888.     int rlen = strlen(Rstr);
  889.     char senabled = 0;
  890.     register ubyte *ptr;
  891.     register int i, col;
  892.     register ED *ep = Ep;
  893.  
  894.     CaseIgnore = ep->IgnoreCase;
  895.     text_sync();
  896.     if (!flen) {
  897.     title("No find pattern");
  898.     Abortcommand = 1;
  899.     return;
  900.     }
  901.  
  902.     col = ep->Column;
  903.     if (col >= strlen(ep->List[ep->Line]))
  904.     col = strlen(ep->List[ep->Line]);
  905.     for (i = ep->Line;;) {
  906.     ptr = ep->List[i];
  907.     if (Srch_sign > 0) {
  908.         while (ptr[col]) {
  909.         if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  910.             goto found;
  911.         senabled = 1;
  912.         ++col;
  913.         }
  914.         senabled = 1;
  915.         if (++i >= ep->Lines)
  916.         break;
  917.         col = 0;
  918.     } else {
  919.         while (col >= 0) {
  920.         if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  921.             goto found;
  922.         senabled = 1;
  923.         --col;
  924.         }
  925.         senabled = 1;
  926.         if (--i < 0)
  927.         break;
  928.         col = strlen(ep->List[i]);
  929.     }
  930.     }
  931.     title("Pattern Not Found");
  932.     Abortcommand = 1;
  933.     return;
  934.  
  935. found:
  936.     ep->Line = i;
  937.     ep->Column = col;
  938.  
  939.     text_load();
  940.     if (Doreplace) {
  941.     if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
  942.         title("Replace: Line Too Long");
  943.         Abortcommand = 1;
  944.         return;
  945.     }
  946.     if (Clen-col-flen >= 0) {
  947.         bmov(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
  948.         bmov(Rstr, Current+col, rlen);
  949.         Clen += rlen-flen;
  950.     }
  951.     text_sync();
  952.     text_redisplaycurrline();
  953.     } else {
  954.     text_sync();
  955.     }
  956. }
  957.  
  958. #asm
  959.         ;   NOTE: assumes that one of the strings is at least
  960.         ;      'len' bytes long, and contains no nulls.  Also,
  961.         ;      returns only 0=success, 1=fail.  NOT A TRUE
  962.         ;      CASE COMPARE... can get confused by control
  963.         ;      chars.
  964.         ;
  965.         ;   4(sp)  = s1
  966.         ;   8(sp)  = s2
  967.         ;   12(sp) = len
  968.  
  969. _case_strncmp:
  970.         movem.l 4(sp),A0/A1
  971.         move.l    12(sp),D0
  972.         move.l    D2,-(sp)
  973.         tst.b    _CaseIgnore
  974.         bne    .csc100
  975.         moveq.l #0,D1        ;set Z bit    case sensitive
  976.         bra    .csc20
  977. .csc10        cmpm.b    (A0)+,(A1)+
  978. .csc20        dbne    D0,.csc10
  979.         bne    .cscfail
  980. .cscsucc    moveq.l #0,D0        ;return true
  981.         move.l    (sp)+,D2
  982.         rts
  983.  
  984. .csc100     moveq.l #0,D1        ;set Z bit    case sensitive
  985.         bra    .csc120
  986. .csc110     move.b    (A0)+,D1        ;XOR two bytes together
  987.         move.b    (A1)+,D2
  988.         eor.b    D2,D1
  989.         and.b    #$DF,D1     ;forget bit 5 (the case)
  990. .csc120     dbne    D0,.csc110
  991.         beq    .cscsucc
  992. .cscfail    moveq.l #1,D0        ;return failure
  993.         move.l    (sp)+,D2
  994.         rts
  995.  
  996. #endasm
  997.  
  998.