home *** CD-ROM | disk | FTP | other *** search
/ Der Mediaplex Sampler - Die 6 von Plex / 6_v_plex.zip / 6_v_plex / DISK5 / DOS_50 / PVIC.ZIP / SENTENCE.C < prev    next >
C/C++ Source or Header  |  1993-04-21  |  6KB  |  220 lines

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