xref: /illumos-gate/usr/src/contrib/ast/src/lib/libast/string/strpsearch.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
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*
strpsearch(const void * tab,size_t num,size_t siz,const char * name,char ** next)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