home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / ce331src.arj / BASIC.C next >
C/C++ Source or Header  |  1991-03-10  |  11KB  |  507 lines

  1. /*
  2.  *    B A S I C . C
  3.  *
  4.  *    purpose:
  5.  *        The routines in this file move the cursor around on the screen. They
  6.  *        compute a new value for the cursor, then adjust dot. The display code
  7.  *        always updates the cursor location, so only moves between lines, or
  8.  *        functions that adjust the top line in the window and invalidate the
  9.  *        framing, are hard.
  10.  */
  11.  
  12. #include <stdio.h>            /* Turbo C++ verison 1.0 */
  13. #include <dos.h>
  14.  
  15. #include <pdefs.h>            /* PforCe version 1.05 (includes jwg.h) */
  16. #include <pf_ansi.h>
  17.  
  18. #include "struct.h"
  19. #include "def.h"
  20. #include "protos.h"
  21.  
  22. /**
  23.  * Move the cursor to the beginning of the current line
  24.  */
  25. int GotoBOL(f, n)
  26.   int    f, n;
  27. {
  28.     curwp->w_doto = 0;
  29.     return(TRUE);
  30. }
  31.  
  32. /**
  33.  * Move the cursor backwards by "n" characters. If "n" is less than zero call
  34.  * "ForwChar" to actually do the move. Otherwise, compute the new cursor
  35.  * location. Error if you try and move out of the buffer. Set the flag if the
  36.  * line pointer for dot changes.
  37.  */
  38. int BackChar(f, n)
  39.   int    f;
  40.   int    n;
  41. {
  42.   LINE    *lp;
  43.  
  44.     if (n < 0)
  45.         return(ForwChar(f, -n));
  46.     while (n--)
  47.     {
  48.         if (curwp->w_doto == 0)
  49.         {
  50.             if ((lp = lback(curwp->w_dotp)) == curbp->b_linep)
  51.                 return(FALSE);
  52.             curwp->w_dotp = lp;
  53.             curwp->w_doto = llength(lp);
  54.             curwp->w_flag |= WFMOVE;
  55.          }
  56.          else
  57.             curwp->w_doto--;
  58.     }
  59.     return(TRUE);
  60. }
  61.  
  62. /**
  63.  * Move the cursor to the end of the current line
  64.  */
  65. int GotoEOL(f, n)
  66.   int    f, n;
  67. {
  68.     curwp->w_doto = llength(curwp->w_dotp);
  69.     return(TRUE);
  70. }
  71.  
  72. /**
  73.  * Move the cursor forward by "n" characters. If "n" is less than zero call
  74.  * "BackChar" to actually do the move. Otherwise, compute the new cursor
  75.  * location, and move dot. Error if you try and move out of the buffer. Set
  76.  * the flag if the line pointer for dot changes.
  77.  */
  78. int ForwChar(f, n)
  79.   int    f;
  80.   int    n;
  81. {
  82.     if (n < 0)
  83.         return(BackChar(f, -n));
  84.     while (n--)
  85.     {
  86.         if (curwp->w_doto == llength(curwp->w_dotp))
  87.         {
  88.             if (curwp->w_dotp == curbp->b_linep)
  89.                 return(FALSE);
  90.             curwp->w_dotp = lforw(curwp->w_dotp);
  91.             curwp->w_doto = 0;
  92.             curwp->w_flag |= WFMOVE;
  93.         }
  94.         else
  95.             curwp->w_doto++;
  96.     }
  97.     return(TRUE);
  98. }
  99.  
  100. /**
  101.  * Move to a particular line  (arg n must be positive for this to do anything)
  102.  */
  103. int GotoLine(f, n)
  104.   int    f, n;
  105. {
  106.   int    status;
  107.   char    arg[NSTRING];  /* buffer to hold argument */
  108.  
  109.     /* get an argument if one doesn't exist */
  110.     if (f == FALSE)
  111.     {
  112.         if ((status = MlReply("Line to goto: ", arg, NSTRING)) != TRUE)
  113.             return(status);
  114.  
  115.         n = cvtatoi(arg);
  116.     }
  117.  
  118.     if (n < 1)                /* if a bogus argument, then leave */
  119.         return(FALSE);
  120.  
  121.     /* first, we go to the start of the buffer */
  122.     curwp->w_dotp = lforw(curbp->b_linep);
  123.     curwp->w_doto = 0;
  124.     return(ForwLine(f, n - 1));
  125. }
  126.  
  127. /**
  128.  * Goto the beginning of the buffer. Massive adjustment of dot. This is
  129.  * considered to be hard motion; it really isn't if the original value of
  130.  * dot is the same as the new value.
  131.  */
  132. int GotoBOB(f, n)
  133.   int    f, n;
  134. {
  135.     curwp->w_dotp = lforw(curbp->b_linep);
  136.     curwp->w_doto = 0;
  137.     curwp->w_flag |= WFHARD;
  138.     return(TRUE);
  139. }
  140.  
  141. /**
  142.  * Move to the end of the buffer. Dot is always put at the end of the file.
  143.  * The standard screen code does most of the hard parts of Update.
  144.  */
  145. int GotoEOB(f, n)
  146.   int    f, n;
  147. {
  148.     curwp->w_dotp = curbp->b_linep;
  149.     curwp->w_doto = 0;
  150.     curwp->w_flag |= WFHARD;
  151.     return(TRUE);
  152. }
  153.  
  154. /**
  155.  * Move forward by full lines. If the number of lines to move is less than
  156.  * zero, call the backward line function to actually do it. The last command
  157.  * controls how the goal column is set. No errors are possible.
  158.  */
  159. int ForwLine(f, n)
  160.   int    f, n;
  161. {
  162.   LINE    *dlp;
  163.  
  164.     if (n < 0)
  165.         return(BackLine(f, -n));
  166.  
  167.     /* if we are on the last line as we start, fail the command */
  168.     if (curwp->w_dotp == curbp->b_linep)
  169.         return(FALSE);
  170.  
  171.     /* if the last command was not a line move, reset the goal column */
  172.     if (!(lastflag & CFLMOV))
  173.         curgoal = GetCurCol(FALSE);
  174.  
  175.     /* flag this command as a line move */
  176.     thisflag |= CFLMOV;
  177.  
  178.     /* and move the point down */
  179.     dlp = curwp->w_dotp;
  180.     while (n-- && dlp != curbp->b_linep)
  181.         dlp = lforw(dlp);
  182.  
  183.     /* resetting the current position */
  184.     curwp->w_dotp = dlp;
  185.     curwp->w_doto = GetGoal(dlp);
  186.     curwp->w_flag |= WFMOVE;
  187.     return(TRUE);
  188. }
  189.  
  190. /**
  191.  * This function is like "ForwLine", but goes backward. The scheme is exactly
  192.  * the same. Check for arguments that are less than zero and call your
  193.  * alternate. Figure out the new line and call "movedot" to perform the
  194.  * motion. No errors are possible.
  195.  */
  196. int BackLine(f, n)
  197.   int    f, n;
  198. {
  199.   LINE    *dlp;
  200.  
  201.     if (n < 0)
  202.         return(ForwLine(f, -n));
  203.  
  204.     /* if we are on the last line as we start, fail the command */
  205.     if (lback(curwp->w_dotp) == curbp->b_linep)
  206.         return(FALSE);
  207.  
  208.     /* if the last command was not a line move, reset the goal column */
  209.     if (!(lastflag & CFLMOV))
  210.         curgoal = GetCurCol(FALSE);
  211.  
  212.     /* flag this command as a line move */
  213.     thisflag |= CFLMOV;
  214.  
  215.     /* and move the point up */
  216.     dlp = curwp->w_dotp;
  217.     while (n-- && lback(dlp) != curbp->b_linep)
  218.         dlp = lback(dlp);
  219.  
  220.     /* resetting the current position */
  221.     curwp->w_dotp = dlp;
  222.     curwp->w_doto = GetGoal(dlp);
  223.     curwp->w_flag |= WFMOVE;
  224.     return(TRUE);
  225. }
  226.  
  227. /**
  228.  * This routine, given a pointer to a LINE, and the current cursor goal
  229.  * column, returns the best choice for the offset. Used by ForwLine() and
  230.  * BackLine().
  231.  */
  232. int GetGoal(dlp)
  233.   LINE    *dlp;
  234. {
  235.   int    c;
  236.   int    col;
  237.   int    newcol;
  238.   int    dbo;
  239.  
  240.     col = 0;
  241.     dbo = 0;
  242.     while (dbo != llength(dlp))
  243.     {
  244.         c = lgetc(dlp, dbo);
  245.         newcol = col;
  246.         if (c == '\t')
  247.             newcol += -(newcol % tabsize) + (tabsize - 1);
  248.         else if (c < 0x20 || c == 0x7f)
  249.             ++newcol;
  250.         ++newcol;
  251.         if (newcol > curgoal)
  252.             break;
  253.         col = newcol;
  254.         ++dbo;
  255.     }
  256.     return(dbo);
  257. }
  258.  
  259. /**
  260.  * Scroll forward by a specified number of lines, or by a full page if no
  261.  * argument. The "2" in the arithmetic on the window size is the overlap.
  262.  * Because this zaps the top line in the display window, we have to do a hard
  263.  * Update.
  264.  */
  265. int ForwPage(f, n)
  266.   int    f;
  267.   int    n;
  268. {
  269.   LINE    *lp;
  270.  
  271.     if (f == FALSE)
  272.     {
  273.         n = curwp->w_ntrows - 2;    /* default scroll */
  274.         if (n <= 0)                 /* forget the overlap if tiny window */
  275.             n = 1;
  276.     }
  277.     else if (n < 0)
  278.         return(BackPage(f, -n));
  279.     lp = curwp->w_linep;
  280.     while (n-- && lp != curbp->b_linep)
  281.         lp = lforw(lp);
  282.     curwp->w_linep = lp;
  283.     curwp->w_dotp = lp;
  284.     curwp->w_doto = 0;
  285.     curwp->w_flag |= WFHARD;
  286.     return(TRUE);
  287. }
  288.  
  289. /**
  290.  * This command is like "ForwPage", but it goes backward. The "2", like
  291.  * above, is the overlap between the two windows. We do a hard Update for
  292.  * exactly the same reason.
  293.  */
  294. int BackPage(f, n)
  295.   int    f;
  296.   int    n;
  297. {
  298.   LINE    *lp;
  299.  
  300.     if (f == FALSE)
  301.     {
  302.         n = curwp->w_ntrows - 2;    /* default scroll */
  303.         if (n <= 0)                 /* don't blow up if the window is tiny */
  304.             n = 1;
  305.     }
  306.     else if (n < 0)
  307.         return(ForwPage(f, -n));
  308.     lp = curwp->w_linep;
  309.     while (n-- && lback(lp) != curbp->b_linep)
  310.         lp = lback(lp);
  311.     curwp->w_linep = lp;
  312.     curwp->w_dotp = lp;
  313.     curwp->w_doto = 0;
  314.     curwp->w_flag |= WFHARD;
  315.     return(TRUE);
  316. }
  317.  
  318. /**
  319.  * Set the mark (f == FALSE) or bookmark 'n' (f == TRUE) to the value of
  320.  * dot in the current window. No errors are possible.
  321.  */
  322. int SetMark(f, n)
  323.   int    f, n;
  324. {
  325. #if BMARKS
  326.   char    buf[NSTRING];
  327.  
  328.     if (f == TRUE)                            /* set bookmark 'n' */
  329.     {
  330.         if (n >= NBMARKS)                    /* make sure it's in range */
  331.             n %= NBMARKS;
  332.  
  333.         curwp->w_bmarkp[n] = curwp->w_dotp;
  334.         curwp->w_bmarko[n] = curwp->w_doto;
  335.         strfmt(buf, "Bookmark %d set", n);
  336.         MlWrite(buf);
  337.     }
  338.     else                                    /* set mark */
  339.     {
  340. #endif
  341.         curwp->w_markp = curwp->w_dotp;
  342.         curwp->w_marko = curwp->w_doto;
  343.         MlWrite("Mark set");
  344. #if BMARKS
  345.     }
  346. #endif
  347.     return(TRUE);
  348. }
  349.  
  350. /**
  351.  * Remove the mark and anchor (f == FALSE) or bookmark 'n' (f == TRUE) in
  352.  * the current window.
  353.  */
  354. int DelMark(f, n)
  355.   int    f, n;
  356. {
  357. #if BMARKS
  358.   char    buf[NSTRING];
  359.  
  360.     if (f == TRUE)                            /* remove bookmark 'n' */
  361.     {
  362.         if (n >= NBMARKS)                    /* make sure it's in range */
  363.             n %= NBMARKS;
  364.  
  365.         curwp->w_bmarkp[n] = NULLLPTR;
  366.         curwp->w_bmarko[n] = 0;
  367.         strfmt(buf, "Bookmark %d removed", n);
  368.         MlWrite(buf);
  369.     }
  370.     else                                    /* remove mark and anchor */
  371.     {
  372. #endif
  373.         curwp->w_markp = NULLLPTR;
  374.         curwp->w_marko = 0;
  375.         curwp->w_anchorp = NULLLPTR;
  376.         curwp->w_anchoro = 0;
  377.         MlWrite("Mark and anchor removed");
  378. #if BMARKS
  379.     }
  380. #endif
  381.     return(TRUE);
  382. }
  383.  
  384. /**
  385.  * Unmark the current buffer's change flag
  386.  */
  387. int UnmarkBuf(f, n)
  388.   int    f, n;
  389. {
  390.     /* UnmarkBuf the buffer */
  391.     curbp->b_flag &= ~BFCHG;
  392.  
  393.     /* UnmarkBuf all the windows into the buffer */
  394.     UpMode();
  395.  
  396.     return(TRUE);
  397. }
  398.  
  399. /**
  400.  * Swap the values of dot and mark in the current window. This is pretty
  401.  * easy, bacause all of the hard work gets done by the standard routine
  402.  * that moves the mark about. The only possible error is "no mark".
  403.  */
  404. int SwapMark(f, n)
  405.   int    f, n;
  406. {
  407.   LINE    *odotp;
  408.   short    odoto;
  409.  
  410.     if (curwp->w_markp == NULLLPTR)
  411.     {
  412.         MlWrite("No mark in this window");
  413.         return(FALSE);
  414.     }
  415.     odotp = curwp->w_dotp;
  416.     odoto = curwp->w_doto;
  417.     curwp->w_dotp = curwp->w_markp;
  418.     curwp->w_doto = curwp->w_marko;
  419.     curwp->w_markp = odotp;
  420.     curwp->w_marko = odoto;
  421.     curwp->w_flag |= WFMOVE;
  422.     return(TRUE);
  423. }
  424.  
  425. /**
  426.  * Set anchor to the value of dot in the current window. No errors are possible.
  427.  */
  428. int SetAnchor(f, n)
  429.   int    f, n;
  430. {
  431.     curwp->w_anchorp = curwp->w_dotp;
  432.     curwp->w_anchoro = curwp->w_doto;
  433.     MlWrite("Anchor set");
  434.     return(TRUE);
  435. }
  436.  
  437. /**
  438.  * Go to a mark (f == FALSE) or bookmark 'n' (f == TRUE).
  439.  */
  440. int GotoMark(f, n)
  441.   int    f, n;
  442. {
  443. #if BMARKS
  444.   char    buf[NSTRING];
  445.  
  446.     if (f == TRUE)                            /* go to bookmark 'n' */
  447.     {
  448.         if (n >= NBMARKS)                    /* make sure it's in range */
  449.             n %= NBMARKS;
  450.  
  451.         if (curwp->w_bmarkp[n] == NULLLPTR)
  452.         {
  453.             strfmt(buf, "Bookmark %d not set in this window", n);
  454.             MlWrite(buf);
  455.             return(FALSE);
  456.         }
  457.  
  458.         curwp->w_dotp = curwp->w_bmarkp[n];
  459.         curwp->w_doto = curwp->w_bmarko[n];
  460.     }
  461.     else
  462.     {
  463. #endif
  464.         if (curwp->w_markp == NULLLPTR)
  465.         {
  466.             MlWrite("Mark not set in this window");
  467.             return(FALSE);
  468.         }
  469.  
  470.         curwp->w_dotp = curwp->w_markp;
  471.         curwp->w_doto = curwp->w_marko;
  472. #if BMARKS
  473.     }
  474. #endif
  475.     curwp->w_flag |= WFMOVE;
  476.     return(TRUE);
  477. }
  478. /**
  479.  * Goto the top line in the window
  480.  */
  481. int GotoTlow(f, n)
  482.   int    f, n;
  483. {
  484.     curgoal = GetCurCol(FALSE);
  485.     curwp->w_dotp = curwp->w_linep;
  486.     curwp->w_doto = GetGoal(curwp->w_dotp);
  487.     curwp->w_flag |= WFMOVE;
  488.     return(TRUE);
  489. }
  490.  
  491. /**
  492.  * Goto the bottom line in the window
  493.  */
  494. int GotoBlow(f, n)
  495.   int    f, n;
  496. {
  497.   int    tmpgoal;
  498.  
  499.     tmpgoal = GetCurCol(FALSE);
  500.     curwp->w_dotp = curwp->w_linep;
  501.     ForwLine(TRUE, curwp->w_ntrows - 1);
  502.     curgoal = tmpgoal;                        /* ForwLine() trashes curgoal */
  503.     curwp->w_doto = GetGoal(curwp->w_dotp);
  504.     curwp->w_flag |= WFMOVE;
  505.     return(TRUE);
  506. }
  507.