Windows test suite & build fixes. VC2003 and VC2008 should both now build. Known...
[dyninst.git] / common / src / util.C
1 #if defined(os_windows)
2 #include "common/h/ntHeaders.h"
3 #endif
4 #include <string>
5 #include "dynutil/h/util.h"
6
7
8 namespace Dyninst {
9 COMMON_EXPORT unsigned addrHashCommon(const Address &addr)
10 {
11    // inspired by hashs of string class
12
13    register unsigned result = 5381;
14
15    register Address accumulator = addr;
16    while (accumulator > 0) {
17       // We use 3 bits at a time from the address
18       result = (result << 4) + result + (accumulator & 0x07);
19       accumulator >>= 3;
20    }
21
22    return result;
23 }
24
25 COMMON_EXPORT unsigned addrHash(const Address & iaddr)
26 {
27    return Dyninst::addrHashCommon(iaddr);
28 }
29
30 COMMON_EXPORT unsigned ptrHash(const void * iaddr)
31 {
32    return Dyninst::addrHashCommon((Address)iaddr);
33 }
34
35 COMMON_EXPORT unsigned ptrHash(void * iaddr)
36 {
37    return Dyninst::addrHashCommon((Address)iaddr);
38 }
39
40 COMMON_EXPORT unsigned addrHash4(const Address &iaddr)
41 {
42    // call when you know that the low 2 bits are 0 (meaning they contribute
43    // nothing to an even hash distribution)
44    return Dyninst::addrHashCommon(iaddr >> 2);
45 }
46
47 COMMON_EXPORT unsigned addrHash16(const Address &iaddr)
48 {
49    // call when you know that the low 4 bits are 0 (meaning they contribute
50    // nothing to an even hash distribution)
51    return Dyninst::addrHashCommon(iaddr >> 4);
52 }
53
54 // string hash grabbed from pdstring
55 unsigned stringhash(const std::string &s)
56 {
57    const char *str = s.c_str();
58    if (!str)
59       return 1; // 0 is reserved for unhashed key
60
61    unsigned h = 5381;
62    while (*str) {
63       h = (h << 5) + h + (unsigned) (*str);
64       str++;
65    }
66    return h==0 ? 1 : h; // 0 is reserved for unhashed key
67 }
68
69 std::string itos(int in)
70 {
71   char buf[16];
72   snprintf(buf, 16, "%d", in);
73   return std::string(buf);
74 }
75
76 std::string utos(unsigned in)
77 {
78   char buf[16];
79   snprintf(buf, 16, "%u", in);
80   return std::string(buf);
81 }
82
83
84 // This function will match string s against pattern p.
85 // Asterisks match 0 or more wild characters, and a question
86 // mark matches exactly one wild character.  In other words,
87 // the asterisk is the equivalent of the regex ".*" and the
88 // question mark is the equivalent of "."
89
90 bool pattern_match( const char *p, const char *s, bool checkCase ) 
91 {
92    //const char *p = ptrn;
93    //char *s = str;
94
95    while ( true ) {
96
97       // If at the end of the pattern, it matches if also at the end of the string
98
99       if ( *p == '\0' )
100          return ( *s == '\0' );
101
102       // Process a '*'
103
104       if ( *p == MULTIPLE_WILDCARD_CHAR ) {
105          ++p;
106
107          // If at the end of the pattern, it matches
108          if ( *p == '\0' )
109             return true;
110
111          // Try to match the remaining pattern for each remaining substring of s
112          for (; *s != '\0'; ++s )
113             if ( pattern_match( p, s, checkCase ) )
114                return true;
115          // Failed
116          return false;
117       }
118
119       // If at the end of the string (and at this point, not of the pattern), it fails
120       if( *s == '\0' )
121          return false;
122
123       // Check if this character matches
124       bool matchChar = false;
125       if ( *p == WILDCARD_CHAR || *p == *s )
126          matchChar = true;
127       else if ( !checkCase ) {
128          if ( *p >= 'A' && *p <= 'Z' && *s == ( *p + ( 'a' - 'A' ) ) )
129             matchChar = true;
130          else if ( *p >= 'a' && *p <= 'z' && *s == ( *p - ( 'a' - 'A' ) ) )
131             matchChar = true;
132       }
133
134       if ( matchChar ) {
135          ++p;
136          ++s;
137          continue;
138       }
139
140       // Did not match
141       return false;
142    }
143 }
144
145 bool wildcardEquiv(const std::string &us, const std::string &them, bool checkCase ) 
146 {
147    if ( us == them )
148       return true;
149    else
150       return pattern_match( us.c_str(), them.c_str(), checkCase );
151 }
152
153
154 } // namespace Dyninst