libidav/davqlparser.c

changeset 80
a2832c054c98
parent 79
59c518ae0641
child 82
0567444f2d76
equal deleted inserted replaced
79:59c518ae0641 80:a2832c054c98
28 28
29 #include "davqlparser.h" 29 #include "davqlparser.h"
30 #include <string.h> 30 #include <string.h>
31 #include <stdio.h> 31 #include <stdio.h>
32 32
33 #define sfmtarg(s) ((int)(s).length), (s).ptr
34
33 static const char* _map_querytype(davqltype_t type) { 35 static const char* _map_querytype(davqltype_t type) {
34 switch(type) { 36 switch(type) {
35 case GET: return "GET"; 37 case GET: return "GET";
36 case SET: return "SET"; 38 case SET: return "SET";
37 default: return "unknown"; 39 default: return "unknown";
38 } 40 }
39 } 41 }
40 42
41 #define dav_debug_print_sstr_t(s) fwrite((s).ptr, 1, (s).length, stdout); 43 static const char* _map_exprtype(davqlexprtype_t type) {
44 switch(type) {
45 case LITERAL: return "LITERAL";
46 case IDENTIFIER: return "IDENTIFIER";
47 case UNARY: return "UNARY";
48 case BINARY: return "BINARY";
49 case LOGICAL: return "LOGICAL";
50 case FUNCCALL: return "FUNCCALL";
51 default: return "unknown";
52 }
53 }
54
55 static const char* _map_operator(davqloperator_t op) {
56 // don't use string array, because enum values may change
57 switch(op) {
58 case ADD: return "+"; case SUB: return "-"; case MUL: return "*";
59 case DIV: return "/"; case AND: return "&"; case OR: return "|";
60 case XOR: return "^"; case NEG: return "~"; case NOT: return "NOT";
61 case LAND: return "AND"; case LOR: return "OR"; case LXOR: return "XOR";
62 case EQ: return "="; case NEQ: return "!="; case LT: return "<";
63 case GT: return ">"; case LE: return "<="; case GE: return ">=";
64 case LIKE: return "LIKE"; case UNLIKE: return "UNLIKE";
65 default: return "unknown";
66 }
67 }
42 68
43 static void dav_debug_ql_stmt_print(DavQLStatement *stmt) { 69 static void dav_debug_ql_stmt_print(DavQLStatement *stmt) {
44 70
45 // Basic information 71 // Basic information
46 printf("Statement: "); 72 printf("Statement: %*s\nType: %s\nField count: %zu",
47 dav_debug_print_sstr_t(stmt->srctext); 73 sfmtarg(stmt->srctext),
48 printf("\nType: %s\nField count: %zu",
49 _map_querytype(stmt->type), 74 _map_querytype(stmt->type),
50 ucx_list_size(stmt->fields)); 75 ucx_list_size(stmt->fields));
51 76
52 // Has wildcard 77 // Has wildcard
53 _Bool wildcard = 0; 78 _Bool wildcard = 0;
56 if (expr->type == IDENTIFIER && 81 if (expr->type == IDENTIFIER &&
57 expr->srctext.length == 1 && *(expr->srctext.ptr) == '*') { 82 expr->srctext.length == 1 && *(expr->srctext.ptr) == '*') {
58 wildcard = 1; 83 wildcard = 1;
59 } 84 }
60 } 85 }
61 printf(" with%s wildcard\n", wildcard?"":"out"); 86 printf(" %s wildcard\nPath: %*s\nHas where clause: %s\n",
62 87 wildcard?"with":"without",
63 // Pathname 88 sfmtarg(stmt->path.srctext),
64 printf("Path: "); 89 stmt->where ? "yes" : "no");
65 dav_debug_print_sstr_t(stmt->path.srctext);
66
67 // Has where clause
68 printf("\nHas where clause: %s\n", stmt->where ? "yes" : "no");
69 if (stmt->type == SET) { 90 if (stmt->type == SET) {
70 printf("Value list size matches: %s", 91 printf("Value list size matches: %s",
71 ucx_list_size(stmt->fields) == ucx_list_size(stmt->setvalues) 92 ucx_list_size(stmt->fields) == ucx_list_size(stmt->setvalues)
72 ? "yes" : "no"); 93 ? "yes" : "no");
73 } 94 }
78 } else { 99 } else {
79 printf("Depth: %zu\n", stmt->depth); 100 printf("Depth: %zu\n", stmt->depth);
80 } 101 }
81 } 102 }
82 103
104 static int dav_debug_ql_expr_selected(DavQLExpression *expr) {
105 if (!expr) {
106 printf("Currently no expression selected.\n");
107 return 0;
108 } else {
109 return 1;
110 }
111 }
112
113 static void dav_debug_ql_expr_print(DavQLExpression *expr) {
114 if (dav_debug_ql_expr_selected(expr)) {
115 sstr_t empty = S("(empty)");
116 printf(
117 "Text: %*s\nType: %s\nOperator: %s\n"
118 "Left hand: %*s\nRight hand: %*s\n",
119 sfmtarg(expr->srctext),
120 _map_exprtype(expr->type),
121 _map_operator(expr->op),
122 sfmtarg(expr->left?expr->left->srctext:empty),
123 sfmtarg(expr->right?expr->right->srctext:empty));
124 }
125 }
126
127 #define DQLD_CMD_Q 0
128 #define DQLD_CMD_PS 1
129 #define DQLD_CMD_PE 2
130 #define DQLD_CMD_P 10
131 #define DQLD_CMD_L 21
132 #define DQLD_CMD_R 22
133 #define DQLD_CMD_H 100
134
83 static int dav_debug_ql_command() { 135 static int dav_debug_ql_command() {
84 printf("Command (type 'h' for help): "); 136 printf("> ");
85 137
86 char buffer[16]; 138 char buffer[16];
87 fgets(buffer, 16, stdin); 139 fgets(buffer, 16, stdin);
88 if (!strcmp(buffer, "q\n")) { 140 if (!strcmp(buffer, "q\n")) {
89 return 0; 141 return DQLD_CMD_Q;
90 } else if (!strcmp(buffer, "ps\n")) { 142 } else if (!strcmp(buffer, "ps\n")) {
91 return 1; 143 return DQLD_CMD_PS;
144 } else if (!strcmp(buffer, "pe\n")) {
145 return DQLD_CMD_PE;
146 } else if (!strcmp(buffer, "p\n")) {
147 return DQLD_CMD_P;
148 } else if (!strcmp(buffer, "l\n")) {
149 return DQLD_CMD_L;
150 } else if (!strcmp(buffer, "r\n")) {
151 return DQLD_CMD_R;
92 } else if (!strcmp(buffer, "h\n")) { 152 } else if (!strcmp(buffer, "h\n")) {
93 return 100; 153 return DQLD_CMD_H;
94 } else { 154 } else {
95 return -1; 155 return -1;
96 } 156 }
97 } 157 }
98 158
100 if (!stmt) { 160 if (!stmt) {
101 fprintf(stderr, "Debug DavQLStatement failed: null pointer"); 161 fprintf(stderr, "Debug DavQLStatement failed: null pointer");
102 return; 162 return;
103 } 163 }
104 164
105 printf("Starting DavQL debugger...\n\n"); 165 printf("Starting DavQL debugger (type 'h' for help)...\n\n");
106 dav_debug_ql_stmt_print(stmt); 166 dav_debug_ql_stmt_print(stmt);
167
168 DavQLExpression *examineexpr = NULL;
107 169
108 while(1) { 170 while(1) {
109 int cmd = dav_debug_ql_command(); 171 int cmd = dav_debug_ql_command();
110 switch (cmd) { 172 switch (cmd) {
111 case 0: return; 173 case DQLD_CMD_Q: return;
112 case 1: dav_debug_ql_stmt_print(stmt); break; 174 case DQLD_CMD_PS: dav_debug_ql_stmt_print(stmt); break;
113 case 100: 175 case DQLD_CMD_PE: dav_debug_ql_expr_print(examineexpr); break;
176 case DQLD_CMD_P:
177 examineexpr = &(stmt->path);
178 dav_debug_ql_expr_print(examineexpr);
179 break;
180 case DQLD_CMD_L:
181 if (dav_debug_ql_expr_selected(examineexpr)) {
182 if (examineexpr->left) {
183 examineexpr = examineexpr->left;
184 dav_debug_ql_expr_print(examineexpr);
185 } else {
186 printf("There is no left subtree.\n");
187 }
188 }
189 break;
190 case DQLD_CMD_R:
191 if (dav_debug_ql_expr_selected(examineexpr)) {
192 if (examineexpr->right) {
193 examineexpr = examineexpr->right;
194 dav_debug_ql_expr_print(examineexpr);
195 } else {
196 printf("There is no right subtree.\n");
197 }
198 }
199 break;
200 case DQLD_CMD_H:
114 printf( 201 printf(
115 "\nCommands:\n" 202 "\nCommands:\n"
203 "p: examine path\n"
116 "ps: print statement information\n" 204 "ps: print statement information\n"
117 "q: quit\n"); 205 "q: quit\n\n"
206 "\nExpression examination:\n"
207 "pe: print expression information\n"
208 "l: enter left subtree\n"
209 "r: enter right subtree\n");
118 break; 210 break;
119 default: printf("unknown command\n"); 211 default: printf("unknown command\n");
120 } 212 }
121 } 213 }
122 } 214 }
125 DavQLStatement *stmt = malloc(sizeof(DavQLStatement)); 217 DavQLStatement *stmt = malloc(sizeof(DavQLStatement));
126 218
127 // default values 219 // default values
128 memset(stmt, 0, sizeof(DavQLStatement)); 220 memset(stmt, 0, sizeof(DavQLStatement));
129 stmt->srctext = srctext; 221 stmt->srctext = srctext;
130 stmt->type = -1; 222 stmt->type = stmt->path.type = stmt->path.op = -1;
131 stmt->depth = SIZE_MAX; 223 stmt->depth = SIZE_MAX;
132 224
133 225
134 return stmt; 226 return stmt;
135 } 227 }

mercurial