efl

Форк
0
/
database_expr_api.c 
296 строк · 9.1 Кб
1
#ifdef HAVE_CONFIG_H
2
# include "config.h"
3
#endif
4

5
#include <Eina.h>
6

7
#include "eolian_database.h"
8

9
EOLIAN_API Eolian_Value
10
eolian_expression_eval(const Eolian_Expression *expr, Eolian_Expression_Mask m)
11
{
12
   Eolian_Value err;
13
   err.type = EOLIAN_EXPR_UNKNOWN;
14
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, err);
15
   return database_expr_eval(NULL, (Eolian_Expression *)expr, m, NULL, NULL);
16
}
17

18
EOLIAN_API Eina_Bool
19
eolian_expression_eval_fill(const Eolian_Expression *expr,
20
                            Eolian_Expression_Mask m, Eolian_Value *val)
21
{
22
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EINA_FALSE);
23
   Eolian_Value ret = database_expr_eval(NULL, (Eolian_Expression *)expr, m,
24
                                         NULL, NULL);
25
   if (ret.type == EOLIAN_EXPR_UNKNOWN)
26
     return EINA_FALSE;
27
   *val = ret;
28
   return EINA_TRUE;
29
}
30

31
static void
32
_append_char_escaped(Eina_Strbuf *buf, char c)
33
{
34
   switch (c)
35
     {
36
      case '\'': eina_strbuf_append(buf, "\\\'"); break;
37
      case '\"': eina_strbuf_append(buf, "\\\""); break;
38
      case '\?': eina_strbuf_append(buf, "\\\?"); break;
39
      case '\\': eina_strbuf_append(buf, "\\\\"); break;
40
      case '\a': eina_strbuf_append(buf, "\\a"); break;
41
      case '\b': eina_strbuf_append(buf, "\\b"); break;
42
      case '\f': eina_strbuf_append(buf, "\\f"); break;
43
      case '\n': eina_strbuf_append(buf, "\\n"); break;
44
      case '\r': eina_strbuf_append(buf, "\\r"); break;
45
      case '\t': eina_strbuf_append(buf, "\\t"); break;
46
      case '\v': eina_strbuf_append(buf, "\\v"); break;
47
      default:
48
         if ((c < 32) || (c > 126))
49
           eina_strbuf_append_printf(buf, "\\x%X", (unsigned char)c);
50
         else
51
           eina_strbuf_append_char(buf, c);
52
         break;
53
     }
54
}
55

56
static void
57
_number_to_str(const Eolian_Value *v, Eina_Strbuf *buf)
58
{
59
   switch (v->type)
60
     {
61
      case EOLIAN_EXPR_INT:
62
        eina_strbuf_append_printf(buf, "%d", v->value.i); break;
63
      case EOLIAN_EXPR_UINT:
64
        eina_strbuf_append_printf(buf, "%uU", v->value.u); break;
65
      case EOLIAN_EXPR_LONG:
66
        eina_strbuf_append_printf(buf, "%ldL", v->value.l); break;
67
      case EOLIAN_EXPR_ULONG:
68
        eina_strbuf_append_printf(buf, "%luUL", v->value.ul); break;
69
      case EOLIAN_EXPR_LLONG:
70
        eina_strbuf_append_printf(buf, "%ldLL", (long)v->value.ll); break;
71
      case EOLIAN_EXPR_ULLONG:
72
        eina_strbuf_append_printf(buf, "%luULL", (unsigned long)v->value.ull);
73
        break;
74
      case EOLIAN_EXPR_FLOAT:
75
        eina_strbuf_append_printf(buf, "%ff", v->value.f); break;
76
      case EOLIAN_EXPR_DOUBLE:
77
        eina_strbuf_append_printf(buf, "%f", v->value.d); break;
78
      default:
79
        break;
80
     }
81
}
82

83
EOLIAN_API Eina_Stringshare *
84
eolian_expression_value_to_literal(const Eolian_Value *val)
85
{
86
   EINA_SAFETY_ON_NULL_RETURN_VAL(val, NULL);
87
   switch (val->type)
88
     {
89
      case EOLIAN_EXPR_BOOL:
90
        return eina_stringshare_add(val->value.b ? "EINA_TRUE"
91
                                                 : "EINA_FALSE");
92
      case EOLIAN_EXPR_NULL:
93
        return eina_stringshare_add("NULL");
94
      case EOLIAN_EXPR_CHAR:
95
        {
96
           char c = val->value.c;
97
           Eina_Strbuf *buf = eina_strbuf_new();
98
           const char *ret;
99
           eina_strbuf_append_char(buf, '\'');
100
           _append_char_escaped(buf, c);
101
           eina_strbuf_append_char(buf, '\'');
102
           ret = eina_stringshare_add(eina_strbuf_string_get(buf));
103
           eina_strbuf_free(buf);
104
           return ret;
105
        }
106
      case EOLIAN_EXPR_STRING:
107
        {
108
           const char *ret;
109
           char *c = (char*)val->value.s;
110
           Eina_Strbuf *buf = eina_strbuf_new();
111
           eina_strbuf_append_char(buf, '\"');
112
           while (*c) _append_char_escaped(buf, *(c++));
113
           eina_strbuf_append_char(buf, '\"');
114
           ret = eina_stringshare_add(eina_strbuf_string_get(buf));
115
           eina_strbuf_free(buf);
116
           return ret;
117
        }
118
      case EOLIAN_EXPR_INT:
119
      case EOLIAN_EXPR_UINT:
120
      case EOLIAN_EXPR_LONG:
121
      case EOLIAN_EXPR_ULONG:
122
      case EOLIAN_EXPR_LLONG:
123
      case EOLIAN_EXPR_ULLONG:
124
      case EOLIAN_EXPR_FLOAT:
125
      case EOLIAN_EXPR_DOUBLE:
126
        {
127
           const char *ret;
128
           Eina_Strbuf *buf = eina_strbuf_new();
129
           _number_to_str(val, buf);
130
           ret = eina_stringshare_add(eina_strbuf_string_get(buf));
131
           eina_strbuf_free(buf);
132
           return ret;
133
        }
134
      default:
135
        return NULL;
136
     }
137
}
138

139
static const char *_binops[] = {
140
    "+", "-", "*", "/", "%",
141
    "==", "!=", ">", "<", ">=", "<=",
142
    "&&", "||",
143
    "&", "|", "^", "<<", ">>"
144
};
145

146
static const char *_unops[] = {
147
    "-", "+", "!", "~"
148
};
149

150
static Eina_Bool
151
_expr_serialize(const Eolian_Expression *expr, Eina_Strbuf *buf, Eina_Bool outer)
152
{
153
   switch (expr->type)
154
     {
155
      case EOLIAN_EXPR_UNKNOWN:
156
        return EINA_FALSE;
157
      case EOLIAN_EXPR_INT:
158
      case EOLIAN_EXPR_UINT:
159
      case EOLIAN_EXPR_LONG:
160
      case EOLIAN_EXPR_ULONG:
161
      case EOLIAN_EXPR_LLONG:
162
      case EOLIAN_EXPR_ULLONG:
163
      case EOLIAN_EXPR_FLOAT:
164
      case EOLIAN_EXPR_DOUBLE:
165
      case EOLIAN_EXPR_STRING:
166
      case EOLIAN_EXPR_CHAR:
167
        {
168
           Eolian_Value v;
169
           v.type = expr->type;
170
           v.value = expr->value;
171
           const char *x = eolian_expression_value_to_literal(&v);
172
           if (!x)
173
             return EINA_FALSE;
174
           eina_strbuf_append(buf, x);
175
           eina_stringshare_del(x);
176
           break;
177
        }
178
      case EOLIAN_EXPR_NULL:
179
        eina_strbuf_append(buf, "null");
180
        break;
181
      case EOLIAN_EXPR_BOOL:
182
        eina_strbuf_append(buf, expr->value.b ? "true" : "false");
183
        break;
184
      case EOLIAN_EXPR_NAME:
185
        {
186
           eina_strbuf_append(buf, expr->value.s);
187
           break;
188
        }
189
      case EOLIAN_EXPR_UNARY:
190
        eina_strbuf_append(buf, _unops[expr->unop]);
191
        _expr_serialize(expr->expr, buf, EINA_FALSE);
192
        break;
193
      case EOLIAN_EXPR_BINARY:
194
        if (!outer)
195
          eina_strbuf_append_char(buf, '(');
196
        _expr_serialize(expr->lhs, buf, EINA_FALSE);
197
        eina_strbuf_append_printf(buf, " %s ", _binops[expr->binop]);
198
        _expr_serialize(expr->rhs, buf, EINA_FALSE);
199
        if (!outer)
200
          eina_strbuf_append_char(buf, ')');
201
        break;
202
      default:
203
        return EINA_FALSE;
204
     }
205
   return EINA_TRUE;
206
}
207

208
EOLIAN_API Eina_Stringshare *
209
eolian_expression_serialize(const Eolian_Expression *expr)
210
{
211
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, NULL);
212
   Eina_Strbuf *buf = eina_strbuf_new();
213
   if (!_expr_serialize(expr, buf, EINA_TRUE))
214
     {
215
        eina_strbuf_free(buf);
216
        return NULL;
217
     }
218
   const char *ret = eina_stringshare_add(eina_strbuf_string_get(buf));
219
   eina_strbuf_free(buf);
220
   return ret;
221
}
222

223
EOLIAN_API Eolian_Expression_Type
224
eolian_expression_type_get(const Eolian_Expression *expr)
225
{
226
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EOLIAN_EXPR_UNKNOWN);
227
   return expr->type;
228
}
229

230
EOLIAN_API Eolian_Binary_Operator
231
eolian_expression_binary_operator_get(const Eolian_Expression *expr)
232
{
233
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EOLIAN_BINOP_INVALID);
234
   EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_BINARY,
235
                                   EOLIAN_BINOP_INVALID);
236
   return expr->binop;
237
}
238

239
EOLIAN_API const Eolian_Expression *
240
eolian_expression_binary_lhs_get(const Eolian_Expression *expr)
241
{
242
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, NULL);
243
   EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_BINARY, NULL);
244
   return expr->lhs;
245
}
246

247
EOLIAN_API const Eolian_Expression *
248
eolian_expression_binary_rhs_get(const Eolian_Expression *expr)
249
{
250
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, NULL);
251
   EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_BINARY, NULL);
252
   return expr->rhs;
253
}
254

255
EOLIAN_API Eolian_Unary_Operator
256
eolian_expression_unary_operator_get(const Eolian_Expression *expr)
257
{
258
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EOLIAN_UNOP_INVALID);
259
   EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_UNARY,
260
                                   EOLIAN_UNOP_INVALID);
261
   return expr->unop;
262
}
263

264
EOLIAN_API const Eolian_Expression *
265
eolian_expression_unary_expression_get(const Eolian_Expression *expr)
266
{
267
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, NULL);
268
   EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type == EOLIAN_EXPR_UNARY, NULL);
269
   return expr->expr;
270
}
271

272
EOLIAN_API Eolian_Value
273
eolian_expression_value_get(const Eolian_Expression *expr)
274
{
275
   Eolian_Value v;
276
   v.type = EOLIAN_EXPR_UNKNOWN;
277
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, v);
278
   EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type != EOLIAN_EXPR_UNKNOWN
279
                                && expr->type != EOLIAN_EXPR_BINARY
280
                                && expr->type != EOLIAN_EXPR_UNARY, v);
281
   v.type  = expr->type;
282
   v.value = expr->value;
283
   return v;
284
}
285

286
EOLIAN_API Eina_Bool
287
eolian_expression_value_get_fill(const Eolian_Expression *expr, Eolian_Value *val)
288
{
289
   EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EINA_FALSE);
290
   EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type != EOLIAN_EXPR_UNKNOWN
291
                                && expr->type != EOLIAN_EXPR_BINARY
292
                                && expr->type != EOLIAN_EXPR_UNARY, EINA_FALSE);
293
   val->type  = expr->type;
294
   val->value = expr->value;
295
   return EINA_TRUE;
296
}
297

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.