agoo 2.5.7 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +38 -0
- data/ext/agoo/agoo.c +11 -2
- data/ext/agoo/bind.c +15 -20
- data/ext/agoo/con.c +32 -25
- data/ext/agoo/debug.c +225 -162
- data/ext/agoo/debug.h +31 -51
- data/ext/agoo/doc.c +278 -5
- data/ext/agoo/doc.h +6 -1
- data/ext/agoo/err.c +1 -0
- data/ext/agoo/err.h +1 -0
- data/ext/agoo/error_stream.c +3 -6
- data/ext/agoo/gqlcobj.c +12 -0
- data/ext/agoo/gqlcobj.h +25 -0
- data/ext/agoo/gqleval.c +520 -0
- data/ext/agoo/gqleval.h +49 -0
- data/ext/agoo/gqlintro.c +1237 -97
- data/ext/agoo/gqlintro.h +8 -0
- data/ext/agoo/gqljson.c +460 -0
- data/ext/agoo/gqljson.h +15 -0
- data/ext/agoo/gqlvalue.c +679 -136
- data/ext/agoo/gqlvalue.h +29 -7
- data/ext/agoo/graphql.c +841 -362
- data/ext/agoo/graphql.h +180 -90
- data/ext/agoo/hook.c +8 -16
- data/ext/agoo/http.c +3 -4
- data/ext/agoo/log.c +22 -25
- data/ext/agoo/log.h +1 -0
- data/ext/agoo/page.c +24 -40
- data/ext/agoo/pub.c +23 -21
- data/ext/agoo/queue.c +2 -4
- data/ext/agoo/ready.c +9 -9
- data/ext/agoo/req.c +80 -5
- data/ext/agoo/req.h +2 -0
- data/ext/agoo/res.c +1 -3
- data/ext/agoo/rgraphql.c +753 -0
- data/ext/agoo/rresponse.c +9 -15
- data/ext/agoo/rserver.c +18 -17
- data/ext/agoo/sdl.c +1264 -120
- data/ext/agoo/sdl.h +8 -1
- data/ext/agoo/sectime.c +136 -0
- data/ext/agoo/sectime.h +19 -0
- data/ext/agoo/server.c +1 -3
- data/ext/agoo/subject.c +2 -4
- data/ext/agoo/text.c +124 -18
- data/ext/agoo/text.h +5 -1
- data/ext/agoo/upgraded.c +2 -4
- data/lib/agoo/version.rb +1 -1
- data/test/base_handler_test.rb +43 -40
- data/test/bind_test.rb +49 -48
- data/test/graphql_test.rb +1019 -0
- data/test/hijack_test.rb +1 -1
- data/test/rack_handler_test.rb +40 -34
- data/test/static_test.rb +33 -32
- metadata +17 -6
data/ext/agoo/debug.h
CHANGED
@@ -3,62 +3,42 @@
|
|
3
3
|
#ifndef AGOO_DEBUG_H
|
4
4
|
#define AGOO_DEBUG_H
|
5
5
|
|
6
|
-
#include
|
6
|
+
#include <stdlib.h>
|
7
7
|
|
8
8
|
#ifdef MEM_DEBUG
|
9
|
-
|
10
|
-
#define
|
11
|
-
#define
|
9
|
+
|
10
|
+
#define AGOO_MALLOC(size) agoo_malloc(size, __FILE__, __LINE__)
|
11
|
+
#define AGOO_ALLOC(ptr, size) agoo_alloc(ptr, size, __FILE__, __LINE__)
|
12
|
+
#define AGOO_REALLOC(ptr, size) agoo_realloc(ptr, size, __FILE__, __LINE__)
|
13
|
+
#define AGOO_STRDUP(str) agoo_strdup(str, __FILE__, __LINE__)
|
14
|
+
#define AGOO_STRNDUP(str, len) agoo_strndup(str, len, __FILE__, __LINE__)
|
15
|
+
|
16
|
+
#define AGOO_FREE(ptr) agoo_free(ptr, __FILE__, __LINE__)
|
17
|
+
#define AGOO_FREED(ptr) agoo_freed(ptr, __FILE__, __LINE__)
|
18
|
+
#define AGOO_MEM_CHECK(ptr) agoo_mem_check(ptr, __FILE__, __LINE__)
|
19
|
+
|
20
|
+
extern void* agoo_malloc(size_t size, const char *file, int line);
|
21
|
+
extern void* agoo_realloc(void *ptr, size_t size, const char *file, int line);
|
22
|
+
extern char* agoo_strdup(const char *str, const char *file, int line);
|
23
|
+
extern char* agoo_strndup(const char *str, size_t len, const char *file, int line);
|
24
|
+
extern void agoo_free(void *ptr, const char *file, int line);
|
25
|
+
extern void agoo_freed(void *ptr, const char *file, int line);
|
26
|
+
extern void agoo_alloc(const void *ptr, size_t size, const char *file, int line);
|
27
|
+
extern void agoo_mem_check(void *ptr, const char *file, int line);
|
28
|
+
|
12
29
|
#else
|
13
|
-
#define DEBUG_ALLOC(var, ptr) { }
|
14
|
-
#define DEBUG_REALLOC(var, orig, ptr) { }
|
15
|
-
#define DEBUG_FREE(var, ptr) { }
|
16
|
-
#endif
|
17
30
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
extern atomic_int mem_graphql_slot;
|
29
|
-
extern atomic_int mem_graphql_type;
|
30
|
-
extern atomic_int mem_graphql_value;
|
31
|
-
extern atomic_int mem_group;
|
32
|
-
extern atomic_int mem_group_path;
|
33
|
-
extern atomic_int mem_header;
|
34
|
-
extern atomic_int mem_hook;
|
35
|
-
extern atomic_int mem_hook_pattern;
|
36
|
-
extern atomic_int mem_http_slot;
|
37
|
-
extern atomic_int mem_log_entry;
|
38
|
-
extern atomic_int mem_log_what;
|
39
|
-
extern atomic_int mem_log_tid;
|
40
|
-
extern atomic_int mem_mime_slot;
|
41
|
-
extern atomic_int mem_page;
|
42
|
-
extern atomic_int mem_page_msg;
|
43
|
-
extern atomic_int mem_page_path;
|
44
|
-
extern atomic_int mem_page_slot;
|
45
|
-
extern atomic_int mem_pub;
|
46
|
-
extern atomic_int mem_qitem;
|
47
|
-
extern atomic_int mem_queue_item;
|
48
|
-
extern atomic_int mem_rack_logger;
|
49
|
-
extern atomic_int mem_req;
|
50
|
-
extern atomic_int mem_res;
|
51
|
-
extern atomic_int mem_res_body;
|
52
|
-
extern atomic_int mem_response;
|
53
|
-
extern atomic_int mem_subject;
|
54
|
-
extern atomic_int mem_text;
|
55
|
-
extern atomic_int mem_to_s;
|
56
|
-
extern atomic_int mem_upgraded;
|
31
|
+
#define AGOO_MALLOC(size) malloc(size)
|
32
|
+
#define AGOO_ALLOC(ptr, size) {}
|
33
|
+
#define AGOO_REALLOC(ptr, size) realloc(ptr, size)
|
34
|
+
#define AGOO_STRDUP(str) strdup(str)
|
35
|
+
#define AGOO_STRNDUP(str, len) strndup(str, len)
|
36
|
+
#define AGOO_FREE(ptr) free(ptr)
|
37
|
+
#define AGOO_FREED(ptr) {}
|
38
|
+
#define AGOO_MEM_CHECK(ptr) {}
|
39
|
+
|
40
|
+
#endif
|
57
41
|
|
58
|
-
extern void debug_add(void *ptr, const char *type, const char *file, int line);
|
59
|
-
extern void debug_update(void *orig, void *ptr, const char *type, const char *file, int line);
|
60
|
-
extern void debug_del(void *ptr, const char *file, int line);
|
61
42
|
extern void debug_report();
|
62
|
-
extern void debug_rreport(); // when called from ruby
|
63
43
|
|
64
44
|
#endif /* AGOO_DEBUG_H */
|
data/ext/agoo/doc.c
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
// Copyright (c) 2018, Peter Ohler, All rights reserved.
|
2
2
|
|
3
|
+
#include <math.h>
|
3
4
|
#include <stdbool.h>
|
4
5
|
#include <stdint.h>
|
5
6
|
#include <stdio.h>
|
@@ -7,6 +8,10 @@
|
|
7
8
|
|
8
9
|
#include "doc.h"
|
9
10
|
#include "gqlvalue.h"
|
11
|
+
#include "graphql.h"
|
12
|
+
|
13
|
+
#define EXP_MAX 100000
|
14
|
+
#define DEC_MAX 16
|
10
15
|
|
11
16
|
static char char_map[256] = "\
|
12
17
|
.........ww..w..................\
|
@@ -18,6 +23,16 @@ pttttttttttttttttttttttttttp.p.t\
|
|
18
23
|
................................\
|
19
24
|
................................";
|
20
25
|
|
26
|
+
static char json_map[256] = "\
|
27
|
+
.........ww..w..................\
|
28
|
+
wpq.....pp..c.p.ttttttttttp..p..\
|
29
|
+
pttttttttttttttttttttttttttp.p.t\
|
30
|
+
.ttttttttttttttttttttttttttppp..\
|
31
|
+
................................\
|
32
|
+
................................\
|
33
|
+
................................\
|
34
|
+
................................";
|
35
|
+
|
21
36
|
void
|
22
37
|
agoo_doc_init(agooDoc doc, const char *str, int len) {
|
23
38
|
if (0 >= len) {
|
@@ -41,6 +56,15 @@ agoo_doc_skip_white(agooDoc doc) {
|
|
41
56
|
return (int)(doc->cur - start);
|
42
57
|
}
|
43
58
|
|
59
|
+
int
|
60
|
+
agoo_doc_skip_jwhite(agooDoc doc) {
|
61
|
+
const char *start = doc->cur;
|
62
|
+
|
63
|
+
for (; 'w' == json_map[*(uint8_t*)doc->cur]; doc->cur++) {
|
64
|
+
}
|
65
|
+
return (int)(doc->cur - start);
|
66
|
+
}
|
67
|
+
|
44
68
|
void
|
45
69
|
agoo_doc_skip_comment(agooDoc doc) {
|
46
70
|
for (; true; doc->cur++) {
|
@@ -54,6 +78,21 @@ agoo_doc_skip_comment(agooDoc doc) {
|
|
54
78
|
}
|
55
79
|
}
|
56
80
|
|
81
|
+
// Return true if found, false if not.
|
82
|
+
bool
|
83
|
+
agoo_doc_skip_to(agooDoc doc, char c) {
|
84
|
+
const char *orig = doc->cur;
|
85
|
+
|
86
|
+
for (; doc->cur < doc->end; doc->cur++) {
|
87
|
+
if (c == *doc->cur) {
|
88
|
+
return true;
|
89
|
+
}
|
90
|
+
}
|
91
|
+
doc->cur = orig;
|
92
|
+
|
93
|
+
return false;
|
94
|
+
}
|
95
|
+
|
57
96
|
void
|
58
97
|
agoo_doc_read_token(agooDoc doc) {
|
59
98
|
if ('t' == char_map[*(uint8_t*)doc->cur] && '9' < *doc->cur) {
|
@@ -150,10 +189,244 @@ agoo_doc_location(agooDoc doc, int *linep, int *colp) {
|
|
150
189
|
*colp = col;
|
151
190
|
}
|
152
191
|
|
153
|
-
gqlValue
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
192
|
+
static gqlValue
|
193
|
+
read_number(agooErr err, agooDoc doc) {
|
194
|
+
int64_t i = 0;
|
195
|
+
int64_t num = 0;
|
196
|
+
int64_t div = 1;
|
197
|
+
int64_t di = 0;
|
198
|
+
long exp = 0;
|
199
|
+
int neg = false;
|
200
|
+
int hasExp = false;
|
201
|
+
int dec_cnt = 0;
|
202
|
+
int d;
|
203
|
+
|
204
|
+
if ('-' == *doc->cur) {
|
205
|
+
doc->cur++;
|
206
|
+
neg = true;
|
207
|
+
} else if ('+' == *doc->cur) {
|
208
|
+
doc->cur++;
|
209
|
+
}
|
210
|
+
for (; '0' <= *doc->cur && *doc->cur <= '9'; doc->cur++) {
|
211
|
+
if (0 < i) {
|
212
|
+
dec_cnt++;
|
213
|
+
}
|
214
|
+
d = *doc->cur - '0';
|
215
|
+
i = i * 10 + d;
|
216
|
+
if (INT64_MAX <= (uint64_t)i) {
|
217
|
+
agoo_doc_err(doc, err, "number is too large");
|
218
|
+
return NULL;
|
219
|
+
}
|
220
|
+
}
|
221
|
+
if ('.' == *doc->cur) {
|
222
|
+
doc->cur++;
|
223
|
+
for (; '0' <= *doc->cur && *doc->cur <= '9'; doc->cur++) {
|
224
|
+
d = (*doc->cur - '0');
|
225
|
+
if (0 < num || 0 < i) {
|
226
|
+
dec_cnt++;
|
227
|
+
}
|
228
|
+
num = num * 10 + d;
|
229
|
+
div *= 10;
|
230
|
+
di++;
|
231
|
+
if (INT64_MAX <= (uint64_t)div || DEC_MAX < dec_cnt) {
|
232
|
+
agoo_doc_err(doc, err, "number has too many digits");
|
233
|
+
return NULL;
|
234
|
+
}
|
235
|
+
}
|
236
|
+
if ('e' == *doc->cur || 'E' == *doc->cur) {
|
237
|
+
int eneg = 0;
|
238
|
+
|
239
|
+
hasExp = true;
|
240
|
+
doc->cur++;
|
241
|
+
if ('-' == *doc->cur) {
|
242
|
+
doc->cur++;
|
243
|
+
eneg = true;
|
244
|
+
} else if ('+' == *doc->cur) {
|
245
|
+
doc->cur++;
|
246
|
+
}
|
247
|
+
for (; '0' <= *doc->cur && *doc->cur <= '9'; doc->cur++) {
|
248
|
+
exp = exp * 10 + (*doc->cur - '0');
|
249
|
+
if (EXP_MAX <= exp) {
|
250
|
+
// TBD maybe just ignore extra and continue till the end
|
251
|
+
agoo_doc_err(doc, err, "number has too many digits");
|
252
|
+
return NULL;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
if (eneg) {
|
256
|
+
exp = -exp;
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}
|
260
|
+
if (hasExp || 0 < num) {
|
261
|
+
long double d = (long double)i * (long double)div + (long double)num;
|
262
|
+
int x = (int)((int64_t)exp - di);
|
263
|
+
|
264
|
+
d = roundl(d);
|
265
|
+
if (0 < x) {
|
266
|
+
d *= powl(10.0L, x);
|
267
|
+
} else if (0 > x) {
|
268
|
+
d /= powl(10.0L, -x);
|
269
|
+
}
|
270
|
+
if (neg) {
|
271
|
+
d = -d;
|
272
|
+
}
|
273
|
+
return gql_float_create(err, (double)d);
|
274
|
+
|
275
|
+
}
|
276
|
+
if (INT32_MAX < i) {
|
277
|
+
if (neg) {
|
278
|
+
return gql_i64_create(err, -i);
|
279
|
+
} else {
|
280
|
+
return gql_i64_create(err, i);
|
281
|
+
}
|
282
|
+
}
|
283
|
+
if (neg) {
|
284
|
+
return gql_int_create(err, (int32_t)-i);
|
285
|
+
}
|
286
|
+
return gql_int_create(err, (int32_t)i);
|
158
287
|
}
|
159
288
|
|
289
|
+
gqlValue
|
290
|
+
agoo_doc_read_value(agooErr err, agooDoc doc, gqlType type) {
|
291
|
+
gqlValue value = NULL;
|
292
|
+
const char *start;
|
293
|
+
|
294
|
+
agoo_doc_skip_white(doc);
|
295
|
+
start = doc->cur;
|
296
|
+
switch (*doc->cur) {
|
297
|
+
case '$':
|
298
|
+
doc->cur++;
|
299
|
+
start++;
|
300
|
+
agoo_doc_read_token(doc);
|
301
|
+
value = gql_var_create(err, start, doc->cur - start);
|
302
|
+
break;
|
303
|
+
case '"': {
|
304
|
+
const char *end;
|
305
|
+
|
306
|
+
start++;
|
307
|
+
if (AGOO_ERR_OK != agoo_doc_read_string(err, doc)) {
|
308
|
+
return NULL;
|
309
|
+
}
|
310
|
+
if ('"' == *start) { // must be a """
|
311
|
+
start += 2;
|
312
|
+
end = doc->cur - 3;
|
313
|
+
} else {
|
314
|
+
end = doc->cur - 1;
|
315
|
+
}
|
316
|
+
value = gql_string_create(err, start, end - start);
|
317
|
+
break;
|
318
|
+
}
|
319
|
+
case '-':
|
320
|
+
case '+':
|
321
|
+
case '0':
|
322
|
+
case '1':
|
323
|
+
case '2':
|
324
|
+
case '3':
|
325
|
+
case '4':
|
326
|
+
case '5':
|
327
|
+
case '6':
|
328
|
+
case '7':
|
329
|
+
case '8':
|
330
|
+
case '9':
|
331
|
+
value = read_number(err, doc);
|
332
|
+
break;
|
333
|
+
case 'n':
|
334
|
+
agoo_doc_read_token(doc);
|
335
|
+
if (doc->cur - start == 4 && 0 == strncmp("null", start, 4)) {
|
336
|
+
value = gql_null_create(err);
|
337
|
+
} else {
|
338
|
+
value = gql_token_create(err, start, doc->cur - start, type);
|
339
|
+
}
|
340
|
+
break;
|
341
|
+
case 't':
|
342
|
+
agoo_doc_read_token(doc);
|
343
|
+
if (doc->cur - start == 4 && 0 == strncmp("true", start, 4)) {
|
344
|
+
value = gql_bool_create(err, true);
|
345
|
+
} else {
|
346
|
+
value = gql_token_create(err, start, doc->cur - start, type);
|
347
|
+
}
|
348
|
+
break;
|
349
|
+
case 'f':
|
350
|
+
agoo_doc_read_token(doc);
|
351
|
+
if (doc->cur - start == 5 && 0 == strncmp("false", start, 5)) {
|
352
|
+
value = gql_bool_create(err, false);
|
353
|
+
} else {
|
354
|
+
value = gql_token_create(err, start, doc->cur - start, type);
|
355
|
+
}
|
356
|
+
break;
|
357
|
+
case '[':
|
358
|
+
if (NULL != type) {
|
359
|
+
if (GQL_LIST != type->kind) {
|
360
|
+
agoo_doc_err(doc, err, "Not a list type");
|
361
|
+
return NULL;
|
362
|
+
}
|
363
|
+
type = type->base;
|
364
|
+
}
|
365
|
+
if (NULL== (value = gql_list_create(err, type))) {
|
366
|
+
return NULL;
|
367
|
+
}
|
368
|
+
doc->cur++;
|
369
|
+
while (doc->cur < doc->end) {
|
370
|
+
gqlValue member;
|
371
|
+
|
372
|
+
agoo_doc_skip_white(doc);
|
373
|
+
if (']' == *doc->cur) {
|
374
|
+
doc->cur++;
|
375
|
+
break;
|
376
|
+
}
|
377
|
+
if (NULL == (member = agoo_doc_read_value(err, doc, type))) {
|
378
|
+
return NULL;
|
379
|
+
}
|
380
|
+
if (AGOO_ERR_OK != gql_list_append(err, value, member)) {
|
381
|
+
return NULL;
|
382
|
+
}
|
383
|
+
}
|
384
|
+
break;
|
385
|
+
case '{':
|
386
|
+
if (NULL == (value = gql_object_create(err))) {
|
387
|
+
return NULL;
|
388
|
+
}
|
389
|
+
//value->type = type; // values are always the base object type
|
390
|
+
doc->cur++;
|
391
|
+
while (doc->cur < doc->end) {
|
392
|
+
char key[256];
|
393
|
+
gqlValue member;
|
394
|
+
|
395
|
+
agoo_doc_skip_white(doc);
|
396
|
+
if ('}' == *doc->cur) {
|
397
|
+
doc->cur++;
|
398
|
+
break;
|
399
|
+
}
|
400
|
+
start = doc->cur;
|
401
|
+
agoo_doc_read_token(doc);
|
402
|
+
if (start == doc->cur) {
|
403
|
+
agoo_doc_err(doc, err, "Expected a member name.");
|
404
|
+
return NULL;
|
405
|
+
}
|
406
|
+
if ((int)sizeof(key) <= doc->cur - start) {
|
407
|
+
agoo_doc_err(doc, err, "Member name too long.");
|
408
|
+
return NULL;
|
409
|
+
}
|
410
|
+
strncpy(key, start, doc->cur - start);
|
411
|
+
key[doc->cur - start] = '\0';
|
412
|
+
agoo_doc_read_token(doc);
|
413
|
+
if (':' != *doc->cur) {
|
414
|
+
agoo_doc_err(doc, err, "Expected a ':' after member name.");
|
415
|
+
return NULL;
|
416
|
+
}
|
417
|
+
doc->cur++;
|
418
|
+
if (NULL == (member = agoo_doc_read_value(err, doc, type))) {
|
419
|
+
return NULL;
|
420
|
+
}
|
421
|
+
if (AGOO_ERR_OK != gql_object_set(err, value, key, member)) {
|
422
|
+
return NULL;
|
423
|
+
}
|
424
|
+
}
|
425
|
+
break;
|
426
|
+
default: // Enum value
|
427
|
+
agoo_doc_read_token(doc);
|
428
|
+
value = gql_token_create(err, start, doc->cur - start, type);
|
429
|
+
break;
|
430
|
+
}
|
431
|
+
return value;
|
432
|
+
}
|
data/ext/agoo/doc.h
CHANGED
@@ -4,9 +4,11 @@
|
|
4
4
|
#define AGOO_DOC_H
|
5
5
|
|
6
6
|
#include <stdarg.h>
|
7
|
+
#include <stdbool.h>
|
7
8
|
|
8
9
|
#include "err.h"
|
9
10
|
|
11
|
+
struct _gqlType;
|
10
12
|
struct _gqlValue;
|
11
13
|
|
12
14
|
typedef struct _agooDoc {
|
@@ -19,8 +21,11 @@ extern void agoo_doc_init(agooDoc doc, const char *str, int len);
|
|
19
21
|
|
20
22
|
extern int agoo_doc_skip_white(agooDoc doc);
|
21
23
|
extern void agoo_doc_skip_comment(agooDoc doc);
|
24
|
+
extern bool agoo_doc_skip_to(agooDoc doc, char c);
|
22
25
|
extern int agoo_doc_read_desc(agooErr err, agooDoc doc);
|
23
26
|
|
27
|
+
extern int agoo_doc_skip_jwhite(agooDoc doc);
|
28
|
+
|
24
29
|
extern void agoo_doc_next_token(agooDoc doc);
|
25
30
|
extern void agoo_doc_read_token(agooDoc doc);
|
26
31
|
|
@@ -29,6 +34,6 @@ extern int agoo_doc_read_string(agooErr err, agooDoc doc);
|
|
29
34
|
extern int agoo_doc_err(agooDoc doc, agooErr err, const char *fmt, ...);
|
30
35
|
extern void agoo_doc_location(agooDoc doc, int *linep, int *colp);
|
31
36
|
|
32
|
-
extern struct _gqlValue* agoo_doc_read_value(agooErr err, agooDoc doc);
|
37
|
+
extern struct _gqlValue* agoo_doc_read_value(agooErr err, agooDoc doc, struct _gqlType *type);
|
33
38
|
|
34
39
|
#endif // AGOO_DOC_H
|
data/ext/agoo/err.c
CHANGED
@@ -71,6 +71,7 @@ agoo_err_str(agooErrCode code) {
|
|
71
71
|
case AGOO_ERR_IN_USE: str = "in use"; break;
|
72
72
|
case AGOO_ERR_TOO_MANY: str = "too many"; break;
|
73
73
|
case AGOO_ERR_TYPE: str = "type error"; break;
|
74
|
+
case AGOO_ERR_EVAL: str = "eval error"; break;
|
74
75
|
default: str = "unknown error"; break;
|
75
76
|
}
|
76
77
|
}
|