1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2007 AT&T Knowledge Ventures * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Knowledge Ventures * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #pragma prototyped 23 /* 24 * Glenn Fowler 25 * AT&T Research 26 */ 27 28 #include <ast.h> 29 #include <ccode.h> 30 #include <ctype.h> 31 32 #if CC_NATIVE == CC_ASCII 33 #define MAP(m,c) (c) 34 #else 35 #define MAP(m,c) m[c] 36 #endif 37 38 /* 39 * return a pointer to the isalpha() identifier matching 40 * name in the CC_ASCII sorted tab of num elements of 41 * size siz where the first member of each 42 * element is a char* 43 * 44 * [xxx] brackets optional identifier characters 45 * * starts optional identifier characters 46 * 47 * 0 returned if name not found 48 * otherwise if next!=0 then it points to the next 49 * unmatched char in name 50 */ 51 52 void* 53 strpsearch(const void* tab, size_t num, size_t siz, const char* name, char** next) 54 { 55 register char* lo = (char*)tab; 56 register char* hi = lo + (num - 1) * siz; 57 register char* mid; 58 #if CC_NATIVE != CC_ASCII 59 register unsigned char* m; 60 #endif 61 register unsigned char* s; 62 register unsigned char* t; 63 register int c; 64 register int v; 65 int sequential = 0; 66 67 #if CC_NATIVE != CC_ASCII 68 m = ccmap(CC_NATIVE, CC_ASCII); 69 #endif 70 c = MAP(m, *((unsigned char*)name)); 71 while (lo <= hi) 72 { 73 mid = lo + (sequential ? 0 : (((hi - lo) / siz) / 2) * siz); 74 if (!(v = c - MAP(m, *(s = *((unsigned char**)mid)))) || *s == '[' && !(v = c - MAP(m, *++s)) && (v = 1)) 75 { 76 t = (unsigned char*)name; 77 for (;;) 78 { 79 if (!v && (*s == '[' || *s == '*')) 80 { 81 v = 1; 82 s++; 83 } 84 else if (v && *s == ']') 85 { 86 v = 0; 87 s++; 88 } 89 else if (!isalpha(*t)) 90 { 91 if (v || !*s) 92 { 93 if (next) 94 *next = (char*)t; 95 return (void*)mid; 96 } 97 if (!sequential) 98 { 99 while ((mid -= siz) >= lo && (s = *((unsigned char**)mid)) && ((c == MAP(m, *s)) || *s == '[' && c == MAP(m, *(s + 1)))); 100 sequential = 1; 101 } 102 v = 1; 103 break; 104 } 105 else if (*t != *s) 106 { 107 v = MAP(m, *t) - MAP(m, *s); 108 break; 109 } 110 else 111 { 112 t++; 113 s++; 114 } 115 } 116 } 117 else if (sequential) 118 break; 119 if (v > 0) 120 lo = mid + siz; 121 else 122 hi = mid - siz; 123 } 124 return 0; 125 } 126