home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / editor / stevie / sentence.c < prev    next >
C/C++ Source or Header  |  1994-01-31  |  5KB  |  216 lines

  1. /*    Find the NEXT/PREVIOUS:
  2.  *    - SENTENCE    findsent (dir)
  3.  *    - PARAGRAPH    findpara (dir)
  4.  *    - FUNCTION    findfunc (dir)
  5.  *
  6.  *    I've split these off from SEARCH.C, because they're alike and
  7.  *    SEARCH.C is a big file already.  findfunc() was already there.
  8.  *    I added findsent() and findpara().  -  Dave Tutelman
  9.  */
  10.  
  11. #include "stevie.h"
  12. #include "ops.h"
  13.  
  14. /* We'll be doing some classification of input characters, into: */
  15. #define    BLANK    0    /* Whitespace */
  16. #define    DOT    1    /* Period, exclamation, q-mark */
  17. #define    EOL    2    /* End-of-line */
  18. #define    OTHER    3    /* Any other non-blank stuff */
  19.  
  20. extern    int    operator;    /* From normal.c, is there an operator
  21.                  * pending?
  22.                  */
  23.  
  24. int
  25. inclass (c)
  26.   char c;
  27. {
  28.     switch (c) {
  29.       case ' ':
  30.       case '\t':
  31.         return BLANK;
  32.       case '.':
  33.       case '!':
  34.       case '?':
  35.         return DOT;
  36.       case '\n':
  37.       case '\r':
  38.       case '\0':
  39.         return EOL;
  40.       default:
  41.         if (c<' ' || c>'~')    return EOL;
  42.         else            return OTHER;
  43.     }
  44. }
  45.  
  46. /* We'll also need to (1) tell if a line is just blanks, and
  47.  *                    (2) skip to the next OTHER character.
  48.  * Here are a couple of functions to do it.
  49.  */
  50.  
  51. bool_t
  52. blankline (line)
  53.   LPTR *line;
  54. {
  55.     char    *p;
  56.     int    class;
  57.  
  58.     if (! line)    return TRUE;
  59.     for (p = line->linep->s; (class=inclass(*p))!=EOL; p++)
  60.         if (class!=BLANK)    return FALSE;
  61.     return TRUE;
  62. }
  63.  
  64.  
  65. LPTR *
  66. skiptotext (lp, dir)
  67.   LPTR *lp;
  68.   int  dir;
  69. {
  70.     LPTR *lpp;
  71.  
  72.     lpp = lp;
  73.     while (inclass( CHAR( lpp )) != OTHER) {
  74.         lpp = (dir==FORWARD) ? nextchar (lpp) : prevchar (lpp);
  75.         if (!lpp) return (lp);        /* hit the end */
  76.     }
  77.     return (lpp);
  78. }
  79.  
  80.  
  81. /*
  82.  * findsent (dir) - Find the next sentence in direction 'dir'
  83.  *
  84.  * Return TRUE if a sentence was found.
  85.  *
  86.  * Algorithm: found end of a sentence if:
  87.  *   FWD - current char is BLANK | EOL and last is DOT.
  88.  *   BKWD- current char is DOT and last is BLANK | EOL.
  89.  * In either case, we then have to skip to text at beginning of next sentence.
  90.  *
  91.  */
  92. bool_t
  93. findsent (dir)
  94. int    dir;
  95. {
  96.     LPTR    *curr, *last;    /* LPTR for current & last characters */
  97.     int    ccurr, clast;    /* class of curr and last characters */
  98.     int    oldindex;    /* need to keep in case search fails */
  99.  
  100.     curr  = Curschar;
  101.     oldindex = curr->index;
  102.     /* Get INTO most recent sentence sentence. */
  103.     if (dir==BACKWARD)
  104.         curr = prevchar (curr);
  105.     curr = skiptotext (curr, BACKWARD);
  106.     ccurr = OTHER;
  107.  
  108.  
  109.     do {
  110.         /* Take a step */
  111.         last = curr; clast = ccurr;
  112.  
  113.         curr = (dir == FORWARD) ? nextchar(curr) : prevchar(curr);
  114.         ccurr = inclass (CHAR( curr ));
  115.  
  116.         /* Test halting condition */
  117.         if (dir==FORWARD &&
  118.             (ccurr==BLANK || ccurr==EOL) && clast==DOT) {
  119.             setpcmark();
  120.             last = skiptotext (last, FORWARD);
  121.             *Curschar = *last;
  122.             return TRUE;
  123.         }
  124.         else if (dir==BACKWARD &&
  125.              ccurr==DOT && (clast==BLANK || clast==EOL)) {
  126.             setpcmark();
  127.             last = skiptotext (last, FORWARD);
  128.             *Curschar = *last;
  129.             return TRUE;
  130.         }
  131.     } while (curr != NULL);
  132.  
  133.     Curschar->index = oldindex;    /* restore if search failed */
  134.     return FALSE;
  135. }
  136.  
  137.  
  138. /*
  139.  * findpara(dir) - Find the next paragraph in direction 'dir'
  140.  *
  141.  * Return TRUE if a paragraph was found.
  142.  *
  143.  * Algorithm: found beginning of paragraph if:
  144.  *   FWD - current line is non-blank and last is blank.
  145.  *   BKWD- current line is blank and last is non-blank.
  146.  * Then we skip to the first non-blank, non-dot text.
  147.  *
  148.  */
  149. bool_t
  150. findpara(dir)
  151. int    dir;
  152. {
  153.     LPTR    *curr, *last;    /* current & last lines */
  154.     LPTR    *marker;    /* end of current para */
  155.     bool_t    bcurr, blast;    /* "blankness" value for lines */
  156.  
  157.     curr  = Curschar;
  158.     bcurr = (dir==FORWARD) ? FALSE : TRUE;    /* keeps us from passing the
  159.                          * text initially. */
  160.  
  161.     do {
  162.         /* Take a step */
  163.         last = curr; blast = bcurr;
  164.         curr = (dir == FORWARD) ? nextline(curr) : prevline(curr);
  165.         bcurr = blankline (curr);
  166.  
  167.         /* Test halting condition */
  168.         if (dir==FORWARD && bcurr && !blast) {
  169.             setpcmark();
  170.             curr = skiptotext (curr, FORWARD);
  171.             *Curschar = *curr;
  172.             return TRUE;
  173.         }
  174.         else if (dir==BACKWARD && bcurr && !blast) {
  175.             setpcmark();
  176.             last = skiptotext (last, FORWARD);
  177.             *Curschar = *last;
  178.             return TRUE;
  179.         }
  180.     } while (curr != NULL);
  181.  
  182.     return FALSE;
  183. }
  184.  
  185.  
  186. /*
  187.  * findfunc(dir) - Find the next function in direction 'dir'
  188.  *
  189.  * Return TRUE if a function was found.
  190.  *
  191.  * Algorithm depends on a style of C coding in which the ONLY '{'
  192.  * in the first column occurs at the beginning of a function definition.
  193.  * This is a good and common style, but not syntactically required by C.
  194.  */
  195. bool_t
  196. findfunc(dir)
  197. int    dir;
  198. {
  199.     LPTR    *curr;
  200.  
  201.     curr = Curschar;
  202.  
  203.     do {
  204.         curr = (dir == FORWARD) ? nextline(curr) : prevline(curr);
  205.  
  206.         if (curr != NULL && curr->linep->s[0] == '{') {
  207.             setpcmark();
  208.             *Curschar = *curr;
  209.             return TRUE;
  210.         }
  211.     } while (curr != NULL);
  212.  
  213.     return FALSE;
  214. }
  215.  
  216.