25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
28 |
28 |
29 #include "davqlparser.h" |
29 #include "davqlparser.h" |
|
30 #include <string.h> |
|
31 #include <stdio.h> |
30 |
32 |
|
33 static const char* _map_querytype(davqltype_t type) { |
|
34 switch(type) { |
|
35 case GET: return "GET"; |
|
36 case SET: return "SET"; |
|
37 default: return "unknown"; |
|
38 } |
|
39 } |
|
40 |
|
41 #define dav_debug_print_sstr_t(s) fwrite((s).ptr, 1, (s).length, stdout); |
|
42 |
|
43 static void dav_debug_ql_stmt_print(DavQLStatement *stmt) { |
|
44 |
|
45 // Basic information |
|
46 printf("Statement: "); |
|
47 dav_debug_print_sstr_t(stmt->srctext); |
|
48 printf("\nType: %s\nField count: %zu", |
|
49 _map_querytype(stmt->type), |
|
50 ucx_list_size(stmt->fields)); |
|
51 |
|
52 // Has wildcard |
|
53 _Bool wildcard = 0; |
|
54 UCX_FOREACH(elm, stmt->fields) { |
|
55 DavQLExpression* expr = (DavQLExpression*)elm->data; |
|
56 if (expr->type == IDENTIFIER && |
|
57 expr->srctext.length == 1 && *(expr->srctext.ptr) == '*') { |
|
58 wildcard = 1; |
|
59 } |
|
60 } |
|
61 printf(" with%s wildcard\n", wildcard?"":"out"); |
|
62 |
|
63 // Pathname |
|
64 printf("Path: "); |
|
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) { |
|
70 printf("Value list size matches: %s", |
|
71 ucx_list_size(stmt->fields) == ucx_list_size(stmt->setvalues) |
|
72 ? "yes" : "no"); |
|
73 } |
|
74 |
|
75 // WITH attributes |
|
76 if (stmt->depth == SIZE_MAX) { |
|
77 printf("Depth: unbound\n"); |
|
78 } else { |
|
79 printf("Depth: %zu\n", stmt->depth); |
|
80 } |
|
81 } |
|
82 |
|
83 static int dav_debug_ql_command() { |
|
84 printf("Command (type 'h' for help): "); |
|
85 |
|
86 char buffer[16]; |
|
87 fgets(buffer, 16, stdin); |
|
88 if (!strcmp(buffer, "q\n")) { |
|
89 return 0; |
|
90 } else if (!strcmp(buffer, "ps\n")) { |
|
91 return 1; |
|
92 } else if (!strcmp(buffer, "h\n")) { |
|
93 return 100; |
|
94 } else { |
|
95 return -1; |
|
96 } |
|
97 } |
|
98 |
|
99 void dav_debug_ql_statement(DavQLStatement *stmt) { |
|
100 if (!stmt) { |
|
101 fprintf(stderr, "Debug DavQLStatement failed: null pointer"); |
|
102 return; |
|
103 } |
|
104 |
|
105 printf("Starting DavQL debugger...\n\n"); |
|
106 dav_debug_ql_stmt_print(stmt); |
|
107 |
|
108 while(1) { |
|
109 int cmd = dav_debug_ql_command(); |
|
110 switch (cmd) { |
|
111 case 0: return; |
|
112 case 1: dav_debug_ql_stmt_print(stmt); break; |
|
113 case 100: |
|
114 printf( |
|
115 "\nCommands:\n" |
|
116 "ps: print statement information\n" |
|
117 "q: quit\n"); |
|
118 break; |
|
119 default: printf("unknown command\n"); |
|
120 } |
|
121 } |
|
122 } |
|
123 |
|
124 DavQLStatement* dav_parse_statement(sstr_t srctext) { |
|
125 DavQLStatement *stmt = malloc(sizeof(DavQLStatement)); |
|
126 |
|
127 // default values |
|
128 memset(stmt, 0, sizeof(DavQLStatement)); |
|
129 stmt->srctext = srctext; |
|
130 stmt->type = -1; |
|
131 stmt->depth = SIZE_MAX; |
|
132 |
|
133 |
|
134 return stmt; |
|
135 } |