home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / me34src.zip / me3 / util / ranger2.c < prev    next >
C/C++ Source or Header  |  1995-01-14  |  3KB  |  109 lines

  1. /* ranger2.c
  2.  * ranger2:
  3.  *   This routine cruises through a sorted list of strings and picks a range
  4.  *     that word falls in.
  5.  *   Blank ("") entries are skipped.
  6.  *   "" does NOT match "".
  7.  *
  8.  * Input:
  9.  *   mover:  Pointer to a function returning a int.
  10.  *     Called to move though the list:
  11.  *       mover(0, (char **)NULL)
  12.  *         Rewind the pointer to the begining of the list.  Doesn't return
  13.  *           anything.
  14.  *       mover(1, (char **)ptr)
  15.  *         Set ptr to point to the key.
  16.  *         Returns:
  17.  *           0 : At the end of the list (ptr not valid).
  18.  *           1 : OK and ptr is valid.
  19.  *     Note:  mover(0, (char **)NULL); mover(1, &ptr); returns a pointer to
  20.  *       the first entry in the list.
  21.  *   word:  What we are looking for in the list.
  22.  *   matched:  Pointer to int.
  23.  *   commonchars:  Pointer to buffer.
  24.  * Output:
  25.  *   matched:  number of characters in word ALSO in at least one item in
  26.  *     list.
  27.  *   commonchars:  given the range word falls in, these are the letters in
  28.  *     common in the range.
  29.  * Returns: TRUE if word is in list else FALSE
  30.  *
  31.  * Fact: The number of letters in commonchars >= matched.
  32.  *
  33.  * Alg:
  34.  *  1. find the max letters in word also in list (match-word)
  35.  *  2. find the range of words in list that have match-word in them
  36.  *  3. find max letters in common in range.
  37.  * C Durland, modified from ranger1.c 1/93
  38.  */
  39.  
  40. /* Copyright 1989-1993 Craig Durland
  41.  *   Distributed under the terms of the GNU General Public License.
  42.  *   Distributed "as is", without warranties of any kind, but comments,
  43.  *     suggestions and bug reports are welcome.
  44.  */
  45.  
  46. #include <const.h>
  47.  
  48. #define REWIND    0
  49. #define NEXT    1
  50.  
  51. ranger2(mover,word,matched,commonchars)
  52.   pfi mover; int *matched; char *word, *commonchars;
  53. {
  54.   char *a = NULL, *b = NULL, c, *ptr;
  55.   register int len, s;
  56.  
  57.   *commonchars = '\0'; *matched = 0;
  58.   if (0 == (len = strlen(word))) return FALSE;    /* "" don't match nuthing */
  59. tryagain:
  60.   mover(REWIND, (char **)NULL);
  61.   while (TRUE)
  62.   {
  63.     if (!mover(NEXT, &ptr)) break;
  64.     if (*ptr == '\0') continue;            /* ignore blank entries */
  65.     if (0 == (s = strncmp(word,ptr,len)))    /* len characters match */
  66.       if (a == NULL) a = ptr;    /* the start of the matched words */
  67.       else b = ptr;        /* the end of the range */
  68.     else
  69.       if (s < 0) break;  /* don't search entire list if don't have to */
  70.   }
  71.  
  72.   if (a == NULL)            /* no match in the list */
  73.     if (0 < len)    /* is there a match on the first n-1 characters? */
  74.       { len--; goto tryagain; }
  75.     else return FALSE;        /* no possible match */
  76.  
  77.   *matched = len;
  78.   if (b == NULL)    /* only one instance of at least part of word */
  79.   {
  80.     strcpy(commonchars,a);
  81.     return (0 == strcmp(word,commonchars));    /* maybe a commplete match */
  82.   }
  83.  
  84.     /* Have a range of words in list that match the first len chars of
  85.      *   word.
  86.      * All words in range have their first len chars in common.
  87.      * Now find the most characters that the words in range have in
  88.      *   common.  This can be lots more than len.
  89.      */
  90.   for (len--; c = *(a + len); len++)
  91.   {
  92.     mover(REWIND, (char **)NULL);
  93.     while (TRUE)    /* move to the start of the range */
  94.     {
  95.       mover(NEXT, &ptr);
  96.       if (ptr == a) break;
  97.     }
  98.     for (; ; mover(NEXT, &ptr))        /* move though the range */
  99.     {
  100.       if (*ptr != '\0' && *(ptr + len) != c) goto done;    /* mismatch */
  101.       if (ptr == b) break;
  102.     }
  103.   }
  104. done:
  105.   strcpy(commonchars,a); commonchars[len] = '\0';
  106.  
  107.   return FALSE;
  108. }
  109.