ruby_rnv 0.2.4 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ #ifndef RUBY_RNV_H
2
+ #define RUBY_RNV_H
3
+
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <stdarg.h>
7
+ #include <fcntl.h> /*open,close*/
8
+ #include <sys/types.h>
9
+ #include <unistd.h> /*open,read,close*/
10
+ #include <string.h> /*strerror*/
11
+ #include <errno.h>
12
+ #include <assert.h>
13
+
14
+ #include <ruby.h>
15
+ #include <ruby/io.h>
16
+
17
+ #include "src/m.h"
18
+ #include "src/s.h"
19
+ #include "src/erbit.h"
20
+ #include "src/drv.h"
21
+ #include "src/rnl.h"
22
+ #include "src/rnv.h"
23
+ #include "src/rnx.h"
24
+ #include "src/ll.h"
25
+ #include "src/er.h"
26
+ #include "src/erbit.h"
27
+ #include "src/rnc.h"
28
+ #include "src/rnd.h"
29
+ #include "src/rx.h"
30
+ #include "src/xsd.h"
31
+ #include "src/rn.h"
32
+
33
+ typedef struct document
34
+ {
35
+ char *fn;
36
+ int start;
37
+ int current;
38
+ int previous;
39
+
40
+ int last_line;
41
+ int last_col;
42
+
43
+ int level;
44
+ int opened;
45
+ int ok;
46
+ char *text;
47
+ int len_txt;
48
+ int n_txt;
49
+ int mixed;
50
+ int nexp;
51
+
52
+ rnv_t *rnv;
53
+ rn_st_t *rn_st;
54
+ rnc_st_t *rnc_st;
55
+ drv_st_t *drv_st;
56
+ rx_st_t *rx_st;
57
+ rnd_st_t *rnd_st;
58
+
59
+ } document_t;
60
+
61
+
62
+ #endif
@@ -0,0 +1,545 @@
1
+ #include "ruby_rnv.h"
2
+
3
+ extern VALUE RNV, SchemaNotLoaded, Error, DataTypeLibrary, Document;
4
+
5
+ static VALUE ruby_nc2arr(rnv_t *rnv, int nc);
6
+
7
+ static VALUE ruby_p2arr(rnv_t *rnv, int p)
8
+ {
9
+ ID id;
10
+ VALUE a1;
11
+ VALUE arr = rb_ary_new2(0);
12
+
13
+ int dt, ps, val, nc, p1;
14
+ switch (RN_P_TYP(p))
15
+ {
16
+ case RN_P_ERROR:
17
+ id = rb_intern("rn_p_error");
18
+ rb_ary_push(arr, ID2SYM(id));
19
+ break;
20
+ case RN_P_NOT_ALLOWED:
21
+ id = rb_intern("rn_p_not_allowed");
22
+ rb_ary_push(arr, ID2SYM(id));
23
+ break;
24
+ case RN_P_EMPTY:
25
+ id = rb_intern("rn_p_empty");
26
+ rb_ary_push(arr, ID2SYM(id));
27
+ break;
28
+ case RN_P_TEXT:
29
+ id = rb_intern("rn_p_text");
30
+ rb_ary_push(arr, ID2SYM(id));
31
+ break;
32
+ case RN_P_CHOICE:
33
+ id = rb_intern("rn_p_choice");
34
+ rb_ary_push(arr, ID2SYM(id));
35
+ break;
36
+ case RN_P_INTERLEAVE:
37
+ id = rb_intern("rn_p_interleave");
38
+ rb_ary_push(arr, ID2SYM(id));
39
+ break;
40
+ case RN_P_GROUP:
41
+ id = rb_intern("rn_p_group");
42
+ rb_ary_push(arr, ID2SYM(id));
43
+ break;
44
+ case RN_P_ONE_OR_MORE:
45
+ id = rb_intern("rn_p_one_or_more");
46
+ rb_ary_push(arr, ID2SYM(id));
47
+ break;
48
+ case RN_P_LIST:
49
+ id = rb_intern("rn_p_list");
50
+ rb_ary_push(arr, ID2SYM(id));
51
+ break;
52
+ case RN_P_DATA:
53
+ id = rb_intern("rn_p_data");
54
+ rn_Data(p, dt, ps);
55
+
56
+ a1 = ruby_nc2arr(rnv, dt);
57
+ rb_ary_push(arr, ID2SYM(id));
58
+ rb_ary_push(arr, a1);
59
+
60
+ break;
61
+ case RN_P_DATA_EXCEPT:
62
+ id = rb_intern("rn_p_data_except");
63
+ rb_ary_push(arr, ID2SYM(id));
64
+ break;
65
+ case RN_P_VALUE:
66
+ id = rb_intern("rn_p_value");
67
+ rn_Value(p, dt, val);
68
+
69
+ a1 = ruby_nc2arr(rnv, dt);
70
+ rb_ary_push(arr, ID2SYM(id));
71
+ rb_ary_push(arr, a1);
72
+ rb_ary_push(arr, rb_str_new2(rnv->rn_string + val));
73
+
74
+ break;
75
+ case RN_P_ATTRIBUTE:
76
+ id = rb_intern("rn_p_attribute");
77
+ rn_Attribute(p, nc, p1);
78
+
79
+ a1 = ruby_nc2arr(rnv, nc);
80
+ rb_ary_push(arr, ID2SYM(id));
81
+ rb_ary_push(arr, a1);
82
+
83
+ break;
84
+ case RN_P_ELEMENT:
85
+ id = rb_intern("rn_p_element");
86
+ rn_Element(p, nc, p1);
87
+
88
+ a1 = ruby_nc2arr(rnv, nc);
89
+ rb_ary_push(arr, ID2SYM(id));
90
+ rb_ary_push(arr, a1);
91
+
92
+ break;
93
+ case RN_P_REF:
94
+ id = rb_intern("rn_p_ref");
95
+ rb_ary_push(arr, ID2SYM(id));
96
+ break;
97
+ case RN_P_AFTER:
98
+ id = rb_intern("rn_p_after");
99
+ rb_ary_push(arr, ID2SYM(id));
100
+ break;
101
+ default:
102
+ assert(0);
103
+ }
104
+ return arr;
105
+ }
106
+
107
+ static VALUE ruby_nc2arr(rnv_t *rnv, int nc)
108
+ {
109
+ ID id;
110
+ VALUE a1, a2;
111
+ VALUE arr = rb_ary_new2(0);
112
+
113
+ int nc1, nc2, uri, name;
114
+ switch (RN_NC_TYP(nc))
115
+ {
116
+ case RN_NC_ERROR:
117
+ id = rb_intern("rn_nc_error");
118
+ rb_ary_push(arr, ID2SYM(id));
119
+ break;
120
+ case RN_NC_NSNAME:
121
+ id = rb_intern("rn_nc_nsname");
122
+ rn_NsName(nc, uri);
123
+
124
+ rb_ary_push(arr, ID2SYM(id));
125
+ rb_ary_push(arr, rb_str_new2(rnv->rn_string + uri));
126
+
127
+ break;
128
+ case RN_NC_QNAME:
129
+ id = rb_intern("rn_nc_qname");
130
+ rn_QName(nc, uri, name);
131
+
132
+ rb_ary_push(arr, ID2SYM(id));
133
+ rb_ary_push(arr, rb_str_new2(rnv->rn_string + uri));
134
+ rb_ary_push(arr, rb_str_new2(rnv->rn_string + name));
135
+
136
+ break;
137
+ case RN_NC_ANY_NAME:
138
+ id = rb_intern("rn_nc_any_name");
139
+ rb_ary_push(arr, ID2SYM(id));
140
+ break;
141
+ case RN_NC_EXCEPT:
142
+ id = rb_intern("rn_nc_except");
143
+ rn_NameClassExcept(nc, nc1, nc2);
144
+
145
+ a1 = ruby_nc2arr(rnv, nc1);
146
+ a2 = ruby_nc2arr(rnv, nc2);
147
+
148
+ rb_ary_push(arr, ID2SYM(id));
149
+ rb_ary_push(arr, a1);
150
+ rb_ary_push(arr, a2);
151
+
152
+ break;
153
+ case RN_NC_CHOICE:
154
+ id = rb_intern("rn_nc_choice");
155
+ rn_NameClassChoice(nc, nc1, nc2);
156
+
157
+ a1 = ruby_nc2arr(rnv, nc1);
158
+ a2 = ruby_nc2arr(rnv, nc2);
159
+
160
+ rb_ary_push(arr, ID2SYM(id));
161
+ rb_ary_push(arr, a1);
162
+ rb_ary_push(arr, a2);
163
+
164
+ break;
165
+ case RN_NC_DATATYPE:
166
+ id = rb_intern("rn_nc_datatype");
167
+ rn_Datatype(nc, uri, name);
168
+
169
+ rb_ary_push(arr, ID2SYM(id));
170
+ rb_ary_push(arr, rb_str_new2(rnv->rn_string + uri));
171
+ rb_ary_push(arr, rb_str_new2(rnv->rn_string + name));
172
+
173
+ break;
174
+ default:
175
+ assert(0);
176
+ }
177
+
178
+ return arr;
179
+ }
180
+
181
+ // convert error code to symbol
182
+ static void ruby_parse_error(VALUE err_obj, int erno, va_list ap)
183
+ {
184
+ va_list lap;
185
+ ID id;
186
+
187
+ if (ap)
188
+ va_copy(lap, ap);
189
+
190
+ switch (erno)
191
+ {
192
+ case (ERBIT_RNC | RNC_ER_IO):
193
+ id = rb_intern("rnc_er_io");
194
+ break;
195
+ case (ERBIT_RNC | RNC_ER_UTF):
196
+ id = rb_intern("rnc_er_urf");
197
+ break;
198
+ case (ERBIT_RNC | RNC_ER_XESC):
199
+ id = rb_intern("rnc_er_xesc");
200
+ break;
201
+ case (ERBIT_RNC | RNC_ER_LEXP):
202
+ id = rb_intern("rnc_er_lexp");
203
+ break;
204
+ case (ERBIT_RNC | RNC_ER_LLIT):
205
+ id = rb_intern("rnc_er_llit");
206
+ break;
207
+ case (ERBIT_RNC | RNC_ER_LILL):
208
+ id = rb_intern("rnc_er_lill");
209
+ break;
210
+ case (ERBIT_RNC | RNC_ER_SEXP):
211
+ id = rb_intern("rnc_er_sexp");
212
+ break;
213
+ case (ERBIT_RNC | RNC_ER_SILL):
214
+ id = rb_intern("rnc_er_still");
215
+ break;
216
+ case (ERBIT_RNC | RNC_ER_NOTGR):
217
+ id = rb_intern("rnc_er_notgr");
218
+ break;
219
+ case (ERBIT_RNC | RNC_ER_EXT):
220
+ id = rb_intern("rnc_er_ext");
221
+ break;
222
+ case (ERBIT_RNC | RNC_ER_DUPNS):
223
+ id = rb_intern("rnc_er_dupns");
224
+ break;
225
+ case (ERBIT_RNC | RNC_ER_DUPDT):
226
+ id = rb_intern("rnc_er_dupdt");
227
+ break;
228
+ case (ERBIT_RNC | RNC_ER_DFLTNS):
229
+ id = rb_intern("rnc_er_dfltns");
230
+ break;
231
+ case (ERBIT_RNC | RNC_ER_DFLTDT):
232
+ id = rb_intern("rnc_er_dfltdt");
233
+ break;
234
+ case (ERBIT_RNC | RNC_ER_NONS):
235
+ id = rb_intern("rnc_er_nons");
236
+ break;
237
+ case (ERBIT_RNC | RNC_ER_NODT):
238
+ id = rb_intern("rnc_er_nodt");
239
+ break;
240
+ case (ERBIT_RNC | RNC_ER_NCEX):
241
+ id = rb_intern("rnc_er_ncex");
242
+ break;
243
+ case (ERBIT_RNC | RNC_ER_2HEADS):
244
+ id = rb_intern("rnc_er_2heads");
245
+ break;
246
+ case (ERBIT_RNC | RNC_ER_COMBINE):
247
+ id = rb_intern("rnc_er_combine");
248
+ break;
249
+ case (ERBIT_RNC | RNC_ER_OVRIDE):
250
+ id = rb_intern("rnc_er_ovride");
251
+ break;
252
+ case (ERBIT_RNC | RNC_ER_EXPT):
253
+ id = rb_intern("rnc_er_excpt");
254
+ break;
255
+ case (ERBIT_RNC | RNC_ER_INCONT):
256
+ id = rb_intern("rnc_er_incont");
257
+ break;
258
+ case (ERBIT_RNC | RNC_ER_NOSTART):
259
+ id = rb_intern("rnc_er_nostart");
260
+ break;
261
+ case (ERBIT_RNC | RNC_ER_UNDEF):
262
+ id = rb_intern("rnc_er_undef");
263
+ break;
264
+
265
+ case (ERBIT_RND | RND_ER_LOOPST):
266
+ id = rb_intern("rnd_er_loopst");
267
+ break;
268
+ case (ERBIT_RND | RND_ER_LOOPEL):
269
+ id = rb_intern("rnd_er_loopel");
270
+ break;
271
+ case (ERBIT_RND | RND_ER_CTYPE):
272
+ id = rb_intern("rnd_er_ctype");
273
+ break;
274
+ case (ERBIT_RND | RND_ER_BADSTART):
275
+ id = rb_intern("rnd_er_badstart");
276
+ break;
277
+ case (ERBIT_RND | RND_ER_BADMORE):
278
+ id = rb_intern("rnd_er_badmore");
279
+ break;
280
+ case (ERBIT_RND | RND_ER_BADEXPT):
281
+ id = rb_intern("rnd_er_badexpt");
282
+ break;
283
+ case (ERBIT_RND | RND_ER_BADLIST):
284
+ id = rb_intern("rnd_er_badlist");
285
+ break;
286
+ case (ERBIT_RND | RND_ER_BADATTR):
287
+ id = rb_intern("rnd_er_badattr");
288
+ break;
289
+
290
+ case (ERBIT_RX | RX_ER_BADCH):
291
+ id = rb_intern("rx_er_badch");
292
+ break;
293
+ case (ERBIT_RX | RX_ER_UNFIN):
294
+ id = rb_intern("rx_er_unfin");
295
+ break;
296
+ case (ERBIT_RX | RX_ER_NOLSQ):
297
+ id = rb_intern("rx_er_nolsq");
298
+ break;
299
+ case (ERBIT_RX | RX_ER_NORSQ):
300
+ id = rb_intern("rx_er_norsq");
301
+ break;
302
+ case (ERBIT_RX | RX_ER_NOLCU):
303
+ id = rb_intern("rx_er_nolcu");
304
+ break;
305
+ case (ERBIT_RX | RX_ER_NORCU):
306
+ id = rb_intern("rx_er_norcu");
307
+ break;
308
+ case (ERBIT_RX | RX_ER_NOLPA):
309
+ id = rb_intern("rx_er_nolpa");
310
+ break;
311
+ case (ERBIT_RX | RX_ER_NORPA):
312
+ id = rb_intern("rx_er_norpa");
313
+ break;
314
+ case (ERBIT_RX | RX_ER_BADCL):
315
+ id = rb_intern("rx_er_badcl");
316
+ break;
317
+ case (ERBIT_RX | RX_ER_NODGT):
318
+ id = rb_intern("rx_er_nodgt");
319
+ break;
320
+ case (ERBIT_RX | RX_ER_DNUOB):
321
+ id = rb_intern("rx_er_dnuob");
322
+ break;
323
+ case (ERBIT_RX | RX_ER_NOTRC):
324
+ id = rb_intern("rx_er_notrc");
325
+ break;
326
+
327
+ case (ERBIT_XSD | XSD_ER_TYP):
328
+ id = rb_intern("xsd_er_typ");
329
+ break;
330
+ case (ERBIT_XSD | XSD_ER_PAR):
331
+ id = rb_intern("xsd_er_par");
332
+ break;
333
+ case (ERBIT_XSD | XSD_ER_PARVAL):
334
+ id = rb_intern("xsd_er_parval");
335
+ break;
336
+ case (ERBIT_XSD | XSD_ER_VAL):
337
+ id = rb_intern("xsd_er_val");
338
+ break;
339
+ case (ERBIT_XSD | XSD_ER_NPAT):
340
+ id = rb_intern("xsd_er_npat");
341
+ break;
342
+ case (ERBIT_XSD | XSD_ER_WS):
343
+ id = rb_intern("xsd_er_ws");
344
+ break;
345
+ case (ERBIT_XSD | XSD_ER_ENUM):
346
+ id = rb_intern("xsd_er_enum");
347
+ break;
348
+
349
+ case (ERBIT_DRV | DRV_ER_NODTL):
350
+ id = rb_intern("drv_er_nodtl");
351
+ break;
352
+
353
+ case (ERBIT_RNV | RNV_ER_ELEM):
354
+ {
355
+ char *ns_uri = va_arg(lap, char *);
356
+ char *tag = va_arg(lap, char *);
357
+
358
+ if (ns_uri)
359
+ rb_iv_set(err_obj, "@ns_uri", rb_str_new2(ns_uri));
360
+
361
+ rb_iv_set(err_obj, "@element", rb_str_new2(tag));
362
+
363
+ id = rb_intern("rnv_er_elem");
364
+ }
365
+ break;
366
+ case (ERBIT_RNV | RNV_ER_AKEY):
367
+ {
368
+ char *ns_uri = va_arg(lap, char *);
369
+ char *attr = va_arg(lap, char *);
370
+
371
+ if (ns_uri)
372
+ rb_iv_set(err_obj, "@ns_uri", rb_str_new2(ns_uri));
373
+
374
+ rb_iv_set(err_obj, "@attr", rb_str_new2(attr));
375
+
376
+ id = rb_intern("rnv_er_akey");
377
+ }
378
+ break;
379
+ case (ERBIT_RNV | RNV_ER_AVAL):
380
+ {
381
+ char *ns_uri = va_arg(lap, char *);
382
+ char *attr = va_arg(lap, char *);
383
+ char *val = va_arg(lap, char *);
384
+
385
+ if (ns_uri)
386
+ rb_iv_set(err_obj, "@ns_uri", rb_str_new2(ns_uri));
387
+
388
+ rb_iv_set(err_obj, "@attr", rb_str_new2(attr));
389
+ rb_iv_set(err_obj, "@value", rb_str_new2(val));
390
+
391
+ id = rb_intern("rnv_er_aval");
392
+ }
393
+ break;
394
+ case (ERBIT_RNV | RNV_ER_EMIS):
395
+ id = rb_intern("rnv_er_emis");
396
+ break;
397
+ case (ERBIT_RNV | RNV_ER_AMIS):
398
+ {
399
+ char *ns_uri = va_arg(lap, char *);
400
+ char *tag = va_arg(lap, char *);
401
+
402
+ if (ns_uri)
403
+ rb_iv_set(err_obj, "@ns_uri", rb_str_new2(ns_uri));
404
+
405
+ rb_iv_set(err_obj, "@element", rb_str_new2(tag));
406
+
407
+ id = rb_intern("rnv_er_amis");
408
+ }
409
+ break;
410
+ case (ERBIT_RNV | RNV_ER_UFIN):
411
+ {
412
+ char *ns_uri = va_arg(lap, char *);
413
+ char *tag = va_arg(lap, char *);
414
+
415
+ if (ns_uri)
416
+ rb_iv_set(err_obj, "@ns_uri", rb_str_new2(ns_uri));
417
+
418
+ rb_iv_set(err_obj, "@element", rb_str_new2(tag));
419
+
420
+ id = rb_intern("rnv_er_ufin");
421
+ }
422
+ break;
423
+ case (ERBIT_RNV | RNV_ER_TEXT):
424
+ id = rb_intern("rnv_er_text");
425
+ break;
426
+ case (ERBIT_RNV | RNV_ER_NOTX):
427
+ id = rb_intern("rnv_er_notx");
428
+ break;
429
+ case (ERBIT_DTL):
430
+ id = rb_intern("dtl");
431
+ break;
432
+ default:
433
+ id = rb_intern("unknown");
434
+ break;
435
+ }
436
+
437
+ rb_iv_set(err_obj, "@code", ID2SYM(id));
438
+
439
+ // return id;
440
+ }
441
+
442
+ VALUE ruby_create_error(VALUE self, VALUE line, VALUE col, int erno, char *format, va_list ap)
443
+ {
444
+ VALUE err_class = Error;
445
+ VALUE err_obj = rb_class_new_instance(0, NULL, err_class);
446
+
447
+ ruby_parse_error(err_obj, erno, ap);
448
+
449
+ VALUE error_str;
450
+
451
+ // do not vsprintf if ap is NULL
452
+ if (ap)
453
+ error_str = rb_vsprintf(format, ap);
454
+ else
455
+ error_str = rb_str_new2(format);
456
+
457
+ // lazyly strip with ruby
458
+ rb_funcall(error_str, rb_intern("strip!"), 0);
459
+
460
+ rb_iv_set(err_obj, "@document", self);
461
+ rb_iv_set(err_obj, "@original_message", error_str);
462
+
463
+ rb_iv_set(err_obj, "@line", line); // set line from sax parser
464
+ rb_iv_set(err_obj, "@col", col); // set col from sax parser
465
+
466
+ rb_iv_set(err_obj, "@required", rb_ary_new2(0));
467
+ rb_iv_set(err_obj, "@allowed", rb_ary_new2(0));
468
+ return err_obj;
469
+ }
470
+
471
+ int ruby_verror_handler(void *data, int erno, char *format, va_list ap)
472
+ {
473
+ VALUE self = (VALUE)data;
474
+ document_t *document;
475
+
476
+ Data_Get_Struct(self, document_t, document);
477
+
478
+ rnv_t *rnv = document->rnv;
479
+
480
+ VALUE errors = rb_iv_get(self, "@errors");
481
+
482
+ if (erno & ERBIT_RNL || erno & ERBIT_RNC || erno & ERBIT_RND)
483
+ {
484
+ VALUE err_obj = ruby_create_error(self, INT2NUM(-1), INT2NUM(-1), erno, format, ap);
485
+ rb_iv_set(err_obj, "@original_expected", rb_str_new2(""));
486
+ rb_ary_push(errors, err_obj);
487
+ }
488
+ else
489
+ {
490
+ VALUE r_last_line = rb_iv_get(self, "@last_line");
491
+ VALUE r_last_col = rb_iv_get(self, "@last_col");
492
+ int last_line = NUM2INT(r_last_line);
493
+ int last_col = NUM2INT(r_last_col);
494
+
495
+ // only one error per line/col
496
+ if (document->last_line != last_line || document->last_col != last_col)
497
+ {
498
+ document->last_line = last_line;
499
+ document->last_col = last_col;
500
+
501
+ VALUE err_obj = ruby_create_error(self, r_last_line, r_last_col, erno, format, ap);
502
+
503
+ VALUE expected = rb_str_new2("");
504
+
505
+ if (erno & ERBIT_RNV)
506
+ {
507
+ if (document->nexp)
508
+ {
509
+ int req = 2, i = 0;
510
+ char *s;
511
+ while (req--)
512
+ {
513
+ rnx_expected(rnv, document->previous, req);
514
+ if (i == rnv->rnx_n_exp)
515
+ continue;
516
+ if (rnv->rnx_n_exp > document->nexp)
517
+ break;
518
+
519
+ expected = rb_str_cat2(expected, (char *)(req ? "required:\n" : "allowed:\n"));
520
+ VALUE expected_arr = rb_ary_new2(0);
521
+
522
+ for (; i != rnv->rnx_n_exp; ++i)
523
+ {
524
+ s = rnx_p2str(rnv, rnv->rnx_exp[i]);
525
+ expected = rb_str_cat2(expected, "\t");
526
+ expected = rb_str_cat2(expected, s);
527
+ expected = rb_str_cat2(expected, "\n");
528
+ m_free(s);
529
+
530
+ rb_ary_push(expected_arr, ruby_p2arr(rnv, rnv->rnx_exp[i]));
531
+ }
532
+
533
+ if (req)
534
+ rb_iv_set(err_obj, "@required", expected_arr);
535
+ else
536
+ rb_iv_set(err_obj, "@allowed", expected_arr);
537
+ }
538
+ }
539
+ }
540
+ rb_iv_set(err_obj, "@original_expected", expected);
541
+
542
+ rb_ary_push(errors, err_obj);
543
+ }
544
+ }
545
+ }