xref: /haiku/src/add-ons/kernel/file_systems/websearchfs/query.c (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
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 
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 
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 
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 
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 
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 
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