static char rcsid[] = "$Id: ranger1.c,v 1.1 1992/09/06 19:31:32 mike Exp $"; /* $Log: ranger1.c,v $ * Revision 1.1 1992/09/06 19:31:32 mike * Initial revision * */ /* ranger1.c * ranger1: * This routine cruises through a list (sorted array of structures, one of * which is a pointer to a string) and picks a range that word falls in. * ???Blank ("") entries are skipped. Depends. Sometimes. I don't think * this part works all that well. * "" does NOT match "". * * Input: * start: A pointer to the string (char *) in the first structure of the * list. Yes, a pointer to a pointer. * blobs: The number of elements in the list. MUST be >= 0. * blobsize: sizeof() each structure in the list. * word: What we are looking for in the list. * Output: * matched: number of characters in word ALSO in at least one item in * list. * commonchars: given the range word falls in, these are the letters in * common in the range. * Returns: TRUE if word is in list else FALSE * * Fact: The number of letters in commonchars >= matched. * * Alg: * 1. find the max letters in word also in list (match-word) * 2. find the range of words in list that have match-word in them * 3. find max letters in common in range. * C Durland */ /* idea for ranger3: pass in incit(): a routine to call when need to move * to next structure. Can be used for linked lists, etc. Note: can't use * incptr as a default unless want to pass in blobsize (or could have * blobsize double as offset). Note: If I do this, start will have to * point to the start of the structure and ranger3 will have to know the * offset of (char *). Could sleeze and subtract offset to find start of * structure. */ /* Copyright 1989, 1990 Craig Durland * Distributed under the terms of the GNU General Public License. * Distributed "as is", without warranties of any kind, but comments, * suggestions and bug reports are welcome. */ #include /* increment a (char **) n bytes */ #define incptr(ptr,n) (char**)((char *)ptr +n) ranger1(start,blobs,blobsize,word,matched,commonchars) char **start, *word, *commonchars; int *matched, blobs, blobsize; { char **a = NULL, **b = NULL, c, **ptr; register int j, len, s; *commonchars = '\0'; *matched = 0; if (0 == (len = strlen(word))) return FALSE; /* "" don't match nuthing */ tryagain: for (j = blobs, ptr = start; j--; ptr = incptr(ptr,blobsize)) { if (**ptr == '\0') continue; /* ignore blank entry */ if ((s = strncmp(word,*ptr,len)) == 0) /* len characters match */ if (a == NULL) a = ptr; /* the start of the matched words */ else b = ptr; /* the end of the range */ else if (s < 0) break; /* don't search entire list if don't have to */ } if (a == NULL) /* no match in the list */ if (len > 0) /* is there a match on the first n-1 characters? */ { len--; goto tryagain; } else return FALSE; /* no possible match */ *matched = len; if (b == NULL) /* only one instance of at least part of word */ { strcpy(commonchars,*a); return (0 == strcmp(word,commonchars)); /* maybe a commplete match */ } /* Have a range of words in list that match the first len chars of * word. * All words in range have their first len chars in common. * Now find the most characters that the words in range have in * common. This can be lots more than len. */ for (len--; c = *(*a + len); len++) /* ???remember "" entries */ for (ptr = incptr(a,blobsize); ptr <= b; ptr = incptr(ptr,blobsize)) if (**ptr != '\0' && *(*ptr+len) != c) goto done; /* mismatch */ done: strcpy(commonchars,*a); commonchars[len] = '\0'; return FALSE; }