1 /*
2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
4 */
5
6 #include "query.h"
7
8 //#define TESTME
9
10 #ifdef _KERNEL_MODE
11 #define printf dprintf
12 #undef TESTME
13 #endif
14
15 #ifdef TESTME
16 #include <stdio.h>
17 #endif
18 #include <stdlib.h>
19 #include <string.h>
20 // ('foo'<>"bar\"")&&!(()||())
21
query_unescape_string(const char * q,const char ** newq,char delim)22 char *query_unescape_string(const char *q, const char **newq, char delim)
23 {
24 int backslash = 0;
25 int i;
26 char *p, *p2;
27
28 if (*q == '*')
29 q++;
30
31 p = malloc(10);
32 if (!p)
33 return NULL;
34 for (i = 0; *q; i++) {
35 if ((i % 10) == 9) {
36 p2 = realloc(p, i+10);
37 if (!p2) {
38 free(p);
39 return NULL;//p;
40 }
41 p = p2;
42 }
43 if (backslash) {
44 backslash = 0;
45 p[i] = *q;
46 } else if (*q == '\\') {
47 backslash = 1;
48 i--;
49 } else if (*q == '\0') {
50 break;
51 } else if (*q == delim) {
52 break;
53 } else {
54 p[i] = *q;
55 if (p[i] == '*')
56 p[i] = ' ';
57 }
58 q++;
59 }
60 p[i] = '\0';
61 if (i > 0 && p[i-1] == ' ')
62 p[i-1] = '\0';
63 if (newq)
64 *newq = q;
65 if (i)
66 return p;
67 free(p);
68 return NULL;
69 }
70
query_strip_bracketed_Cc(char * str)71 char *query_strip_bracketed_Cc(char *str)
72 {
73 char *p = str;
74 char c, C;
75 while (*p) {
76 if (*p == '[') {
77 if (p[1] && p[2] && p[3] == ']') {
78 c = p[1];
79 C = p[2];
80 //printf("cC = %c%c\n", c, C);
81 if (C >= 'a' && C <= 'z' && (c == C + 'A' - 'a'))
82 *p = C;
83 else if (c >= 'a' && c <= 'z' && (C == c + 'A' - 'a'))
84 *p = c;
85 if (*p != '[') {
86 strcpy(p+1, p + 4);
87 }
88 }
89 }
90 p++;
91 }
92 return str;
93 }
94
95 enum pqs_state {
96 QS_UNKNOWN,
97 QS_PAREN,
98 QS_QTR,
99 QS_
100 };
101
102 /*
103 static const char *parse_qs_r(const char *query, query_exp *tree)
104 {
105 int parens = 0;
106 return NULL;
107 }
108 */
109
query_parse(const char * query,query_exp ** tree)110 status_t query_parse(const char *query, query_exp **tree)
111 {
112 //query_exp *t;
113
114 return B_OK;
115 }
116
117 #ifdef TESTME
118
strqop(query_op op)119 const char *strqop(query_op op)
120 {
121 switch (op) {
122 #define QOP(_op) case _op: return #_op
123 QOP(B_INVALID_OP);
124 QOP(B_EQ);
125 QOP(B_GT);
126 QOP(B_GE);
127 QOP(B_LT);
128 QOP(B_LE);
129 QOP(B_NE);
130 QOP(B_CONTAINS);
131 QOP(B_BEGINS_WITH);
132 QOP(B_ENDS_WITH);
133 QOP(B_AND);
134 QOP(B_OR);
135 QOP(B_NOT);
136 #undef QOP
137 default: return "B_?_OP";
138 }
139 }
140
141 #define INDC '#'
142
dump_query_tree(query_exp * tree,int indent)143 void dump_query_tree(query_exp *tree, int indent)
144 {
145 int i;
146 if (!tree)
147 return;
148 if (tree->op >= B_AND) {
149 for (i=0;i<indent;i++) printf("%c", INDC);
150 printf(": %s {\n", strqop(tree->op));
151 dump_query_tree(tree->lv.exp, indent+1);
152 dump_query_tree(tree->rv.exp, indent+1);
153 for (i=0;i<indent;i++) printf("%c", INDC);
154 printf("}\n");
155 } else {
156 for (i=0;i<indent;i++) printf("%c", INDC);
157 printf(": {%s} %s {%s}\n", tree->lv.str, strqop(tree->op), tree->rv.str);
158 }
159 }
160
main(int argc,char ** argv)161 int main(int argc, char **argv)
162 {
163 status_t err;
164 query_exp *tree;
165 char *p;
166 if (argc < 2)
167 return 1;
168 /*
169 err = query_parse(argv[1], &tree);
170 if (err) {
171 printf("parse_query_string: %s\n", strerror(err));
172 return 1;
173 }
174 dump_query_tree(tree, 0);
175 */
176 if (!strncmp(argv[1], "((name==\"*", 10)) {
177 argv[1] += 10;
178 }
179 p = query_unescape_string(argv[1], NULL, '"');
180 printf("'%s'\n", p);
181 query_strip_bracketed_Cc(p);
182 printf("'%s'\n", p);
183 return 0;
184 }
185 #endif
186