1/**
2 * \file
3 * \brief Header file containing definitions for the record ast.
4 */
5
6/*
7 * Copyright (c) 2011, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef OCTOPUS_AST_H_
16#define OCTOPUS_AST_H_
17
18#include <stdlib.h>
19#include <string.h>
20
21#ifndef TEST_PARSER
22#include <barrelfish/barrelfish.h>
23#include <octopus/definitions.h>
24#else
25#define MAX_QUERY_LENGTH (10*1024)
26#define SYS_ERR_OK 0
27#define OCT_ERR_PARSER_FAIL 2
28typedef long errval_t;
29typedef long int64_t;
30static int err_is_ok(errval_t err)
31{
32    return err == 0;
33}
34#endif
35
36struct oct_parser_state {
37    void* scanner;
38    errval_t err;
39    struct ast_object* ast;
40};
41
42struct string_buffer {
43    // Buffer overflow should not be a problem as long as
44    // we always check client input against MAX_QUERY_LENGTH
45    char buffer[MAX_QUERY_LENGTH];
46    char* ptr;
47};
48
49enum constraint_type {
50    constraint_GT,
51    constraint_GE,
52    constraint_LT,
53    constraint_LE,
54    constraint_EQ,
55    constraint_NE,
56    constraint_REGEX
57};
58
59enum node_type {
60    nodeType_Unset, // To detect errors
61    nodeType_Float,
62    nodeType_Constant,
63    nodeType_Boolean,
64    nodeType_String,
65    nodeType_Ident,
66    nodeType_Attribute,
67    nodeType_Pair,
68    nodeType_Constraint,
69    nodeType_Object,
70    nodeType_Scan,
71    nodeType_Variable,
72};
73
74struct node_record {
75    struct ast_object* name;
76    struct ast_object* attrs;
77    struct ast_object* constraints;
78};
79
80struct node_constant {
81    int64_t value;
82};
83
84struct node_boolean {
85    int value;
86};
87
88struct node_float {
89    double value;
90};
91
92struct node_ident {
93    char* str;
94};
95
96struct node_string {
97    char* str;
98};
99
100struct node_scan {
101    char c;
102};
103
104struct node_variable {
105};
106
107struct node_constraint {
108    enum constraint_type op;
109    struct ast_object* value;
110};
111
112struct node_attribute {
113    struct ast_object* attr;
114    struct ast_object* next;
115};
116
117struct node_pair {
118    struct ast_object* left;
119    struct ast_object* right;
120};
121
122struct ast_object {
123    enum node_type type;
124
125    union {
126        struct node_constant cn;
127        struct node_constraint cnsn;
128        struct node_scan scn;
129        struct node_boolean bn;
130        struct node_float fn;
131        struct node_ident in;
132        struct node_string sn;
133        struct node_attribute an;
134        struct node_pair pn;
135        struct node_record on;
136        struct node_variable nv;
137    } u;
138};
139
140errval_t generate_ast(const char* input, struct ast_object** record);
141void free_ast(struct ast_object* p);
142
143void ast_append_attribute(struct ast_object*, struct ast_object*);
144struct ast_object* ast_find_attribute(struct ast_object*, char*);
145struct ast_object* ast_remove_attribute(struct ast_object*, char*);
146
147static inline struct ast_object* ast_alloc_node(void)
148{
149    struct ast_object* p = malloc(sizeof(struct ast_object));
150    if (p == NULL) {
151        assert(!"no more mem, bad!\n");
152        // TODO how to abort parsing here to free up space?
153    }
154    memset(p, 0, sizeof(struct ast_object));
155
156    return p;
157}
158
159static inline struct ast_object* ast_boolean(int value)
160{
161    struct ast_object* p = ast_alloc_node();
162
163    p->type = nodeType_Boolean;
164    p->u.bn.value = value;
165
166    return p;
167}
168
169static inline struct ast_object* ast_variable(void)
170{
171    struct ast_object* p = ast_alloc_node();
172
173    p->type = nodeType_Variable;
174
175    return p;
176}
177
178static inline struct ast_object* ast_constraints(enum constraint_type op,
179        struct ast_object* value)
180{
181    struct ast_object* p = ast_alloc_node();
182
183    p->type = nodeType_Constraint;
184    p->u.cnsn.op = op;
185    p->u.cnsn.value = value;
186
187    return p;
188}
189
190static inline struct ast_object* ast_floatingpoint(double value)
191{
192    struct ast_object* p = ast_alloc_node();
193
194    p->type = nodeType_Float;
195    p->u.fn.value = value;
196
197    return p;
198}
199
200static inline struct ast_object* ast_scan(char c)
201{
202    struct ast_object* p = ast_alloc_node();
203
204    p->type = nodeType_Scan;
205    p->u.scn.c = c;
206
207    return p;
208}
209
210static inline struct ast_object* ast_object(struct ast_object* name,
211        struct ast_object* attrs)
212{
213    struct ast_object* p = ast_alloc_node();
214
215    p->type = nodeType_Object;
216    p->u.on.name = name;
217    p->u.on.attrs = attrs;
218
219    return p;
220}
221
222static inline struct ast_object* ast_attribute(struct ast_object* attr,
223        struct ast_object* next)
224{
225    struct ast_object* p = ast_alloc_node();
226
227    p->type = nodeType_Attribute;
228    p->u.an.attr = attr;
229    p->u.an.next = next;
230
231    return p;
232}
233
234static inline struct ast_object* ast_pair(struct ast_object* left,
235        struct ast_object* right)
236{
237    struct ast_object* p = ast_alloc_node();
238
239    p->type = nodeType_Pair;
240    p->u.pn.left = left;
241    p->u.pn.right = right;
242
243    return p;
244}
245
246static inline struct ast_object* ast_ident(char* str)
247{
248    struct ast_object* p = ast_alloc_node();
249
250    p->type = nodeType_Ident;
251    p->u.in.str = str;
252
253    return p;
254}
255
256static inline struct ast_object* ast_string(char* str)
257{
258    struct ast_object* p = ast_alloc_node();
259
260    p->type = nodeType_String;
261    p->u.sn.str = str;
262
263    return p;
264}
265
266static inline struct ast_object* ast_num(int64_t value)
267{
268    struct ast_object* p = ast_alloc_node();
269
270    p->type = nodeType_Constant;
271    p->u.cn.value = value;
272
273    return p;
274}
275
276#endif // OCTOPUS_AST_H_
277