1N/A/***********************************************************************
1N/A* *
1N/A* This software is part of the ast package *
1N/A* Copyright (c) 1985-2011 AT&T Intellectual Property *
1N/A* and is licensed under the *
1N/A* Common Public License, Version 1.0 *
1N/A* by AT&T Intellectual Property *
1N/A* *
1N/A* A copy of the License is available at *
1N/A* http://www.opensource.org/licenses/cpl1.0.txt *
1N/A* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1N/A* *
1N/A* Information and Software Systems Research *
1N/A* AT&T Research *
1N/A* Florham Park NJ *
1N/A* *
1N/A* Glenn Fowler <gsf@research.att.com> *
1N/A* David Korn <dgk@research.att.com> *
1N/A* Phong Vo <kpv@research.att.com> *
1N/A* *
1N/A***********************************************************************/
1N/A#pragma prototyped
1N/A/*
1N/A * Glenn Fowler
1N/A * AT&T Research
1N/A */
1N/A
1N/A#include <ast.h>
1N/A#include <ccode.h>
1N/A#include <ctype.h>
1N/A
1N/A#if CC_NATIVE == CC_ASCII
1N/A#define MAP(m,c) (c)
1N/A#else
1N/A#define MAP(m,c) m[c]
1N/A#endif
1N/A
1N/A/*
1N/A * return a pointer to the isalpha() identifier matching
1N/A * name in the CC_ASCII sorted tab of num elements of
1N/A * size siz where the first member of each
1N/A * element is a char*
1N/A *
1N/A * [xxx] brackets optional identifier characters
1N/A * * starts optional identifier characters
1N/A *
1N/A * 0 returned if name not found
1N/A * otherwise if next!=0 then it points to the next
1N/A * unmatched char in name
1N/A */
1N/A
1N/Avoid*
1N/Astrpsearch(const void* tab, size_t num, size_t siz, const char* name, char** next)
1N/A{
1N/A register char* lo = (char*)tab;
1N/A register char* hi = lo + (num - 1) * siz;
1N/A register char* mid;
1N/A#if CC_NATIVE != CC_ASCII
1N/A register unsigned char* m;
1N/A#endif
1N/A register unsigned char* s;
1N/A register unsigned char* t;
1N/A register int c;
1N/A register int v;
1N/A int sequential = 0;
1N/A
1N/A#if CC_NATIVE != CC_ASCII
1N/A m = ccmap(CC_NATIVE, CC_ASCII);
1N/A#endif
1N/A c = MAP(m, *((unsigned char*)name));
1N/A while (lo <= hi)
1N/A {
1N/A mid = lo + (sequential ? 0 : (((hi - lo) / siz) / 2) * siz);
1N/A if (!(v = c - MAP(m, *(s = *((unsigned char**)mid)))) || *s == '[' && !(v = c - MAP(m, *++s)) && (v = 1))
1N/A {
1N/A t = (unsigned char*)name;
1N/A for (;;)
1N/A {
1N/A if (!v && (*s == '[' || *s == '*'))
1N/A {
1N/A v = 1;
1N/A s++;
1N/A }
1N/A else if (v && *s == ']')
1N/A {
1N/A v = 0;
1N/A s++;
1N/A }
1N/A else if (!isalpha(*t))
1N/A {
1N/A if (v || !*s)
1N/A {
1N/A if (next)
1N/A *next = (char*)t;
1N/A return (void*)mid;
1N/A }
1N/A if (!sequential)
1N/A {
1N/A while ((mid -= siz) >= lo && (s = *((unsigned char**)mid)) && ((c == MAP(m, *s)) || *s == '[' && c == MAP(m, *(s + 1))));
1N/A sequential = 1;
1N/A }
1N/A v = 1;
1N/A break;
1N/A }
1N/A else if (*t != *s)
1N/A {
1N/A v = MAP(m, *t) - MAP(m, *s);
1N/A break;
1N/A }
1N/A else
1N/A {
1N/A t++;
1N/A s++;
1N/A }
1N/A }
1N/A }
1N/A else if (sequential)
1N/A break;
1N/A if (v > 0)
1N/A lo = mid + siz;
1N/A else
1N/A hi = mid - siz;
1N/A }
1N/A return 0;
1N/A}