1 /* sdb - MIT - Copyright 2015-2016 - pancake */
2
3 #include "sdb.h"
4 #include <ctype.h>
5
haveSuffix(const char * glob,int glob_len,const char * sfx)6 static inline int haveSuffix(const char *glob, int glob_len, const char *sfx) {
7 const int sfx_len = strlen (sfx);
8 return (glob_len>sfx_len && !strcmp (glob+glob_len-sfx_len, sfx));
9 }
10
havePrefix(const char * glob,int glob_len,const char * pfx)11 static inline int havePrefix(const char *glob, int glob_len, const char *pfx) {
12 const int pfx_len = strlen (pfx);
13 return (pfx_len<glob_len && !strncmp (glob, pfx, pfx_len));
14 }
15
16 enum MatchFlag {
17 SDB_LIKE_NONE = 0,
18 SDB_LIKE_ICASE = 1, // ?i
19 SDB_LIKE_START = 2, // ^
20 SDB_LIKE_END = 4, // $
21 SDB_LIKE_BASE64 = 8 // %
22 };
23
mycmp(const char * a,const char * b,int n,int any)24 static inline int mycmp(const char *a, const char *b, int n, int any) {
25 int i, j;
26 for (i = j = 0; a[i] && b[j] && j < n; i++) {
27 if (tolower ((const ut8)a[i]) == tolower ((const ut8)b[j])) {
28 j++;
29 } else {
30 if (!any) {
31 return 0;
32 }
33 j = 0;
34 }
35 }
36 return any? j != n: 1;
37 }
38
strstr2(const char * a,const char * b,int n)39 static inline int strstr2(const char *a, const char *b, int n) {
40 int i, j;
41 for (i = j = 0; a[i] && b[j] && j < n; i++) {
42 if (a[i] == b[j]) {
43 j++;
44 } else {
45 j = 0;
46 }
47 }
48 return j == n;
49 }
50
compareString(const char * a,const char * b,int blen,int flags)51 static inline bool compareString(const char *a, const char *b, int blen, int flags) {
52 const int start = flags & SDB_LIKE_START;
53 const int end = flags & SDB_LIKE_END;
54 char *aa = NULL;
55 int alen;
56 bool ret = false;
57 if (!a || !b || blen < 0) {
58 return 0;
59 }
60 if (flags & SDB_LIKE_BASE64) {
61 aa = (char*)sdb_decode (a, &alen);
62 if (!aa) {
63 return 0;
64 }
65 a = (const char *)aa;
66 } else {
67 alen = strlen (a);
68 }
69 if (blen <= alen) {
70 if (flags & SDB_LIKE_ICASE) {
71 if (start && end) ret = (alen==blen && !mycmp (a, b, blen, 0));
72 else if (start) ret = !mycmp (a, b, blen, 0);
73 else if (end) ret = !mycmp (a+(alen-blen), b, blen, 0);
74 else ret = !mycmp (a, b, blen, 1);
75 } else {
76 if (start && end) ret = (alen==blen && !strncmp (a, b, blen));
77 else if (start) ret = !strncmp (a, b, blen);
78 else if (end) ret = !strncmp (a+(alen-blen), b, blen);
79 else ret = strstr2 (a, b, blen);
80 }
81 }
82 free (aa);
83 return ret;
84 }
85
sdb_match(const char * str,const char * glob)86 SDB_API bool sdb_match (const char *str, const char *glob) {
87 int glob_len, flags = SDB_LIKE_NONE;
88 if (!str || !glob) {
89 return false;
90 }
91 glob_len = strlen (glob);
92 if (haveSuffix (glob, glob_len, "?i")) {
93 glob_len -= 2;
94 flags |= SDB_LIKE_ICASE;
95 }
96 if (havePrefix (glob, glob_len, "%")) {
97 glob++;
98 glob_len--;
99 flags |= SDB_LIKE_BASE64;
100 }
101 if (havePrefix (glob, glob_len, "^")) {
102 glob++;
103 glob_len--;
104 flags |= SDB_LIKE_START;
105 }
106 if (haveSuffix (glob, glob_len, "$")) {
107 glob_len--;
108 flags |= SDB_LIKE_END;
109 }
110 return compareString (str, glob, glob_len, flags);
111 }
112