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