ruby_rnv 0.3.0 → 0.5.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.
@@ -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,548 @@
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, VALUE xpath, 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, "@xpath", xpath); // set line from sax parser
467
+
468
+ rb_iv_set(err_obj, "@required", rb_ary_new2(0));
469
+ rb_iv_set(err_obj, "@allowed", rb_ary_new2(0));
470
+ return err_obj;
471
+ }
472
+
473
+ int ruby_verror_handler(void *data, int erno, char *format, va_list ap)
474
+ {
475
+ VALUE self = (VALUE)data;
476
+ document_t *document;
477
+
478
+ Data_Get_Struct(self, document_t, document);
479
+
480
+ rnv_t *rnv = document->rnv;
481
+
482
+ VALUE errors = rb_iv_get(self, "@errors");
483
+
484
+ if (erno & ERBIT_RNL || erno & ERBIT_RNC || erno & ERBIT_RND)
485
+ {
486
+ VALUE err_obj = ruby_create_error(self, INT2NUM(-1), INT2NUM(-1), Qnil, erno, format, ap);
487
+ rb_iv_set(err_obj, "@original_expected", rb_str_new2(""));
488
+ rb_ary_push(errors, err_obj);
489
+ }
490
+ else
491
+ {
492
+ VALUE r_last_line = rb_iv_get(self, "@last_line");
493
+ VALUE r_last_col = rb_iv_get(self, "@last_col");
494
+ int last_line = NUM2INT(r_last_line);
495
+ int last_col = NUM2INT(r_last_col);
496
+ int xpath = NUM2INT(r_last_col);
497
+
498
+ // only one error per line/col
499
+ // if (document->last_line != last_line || document->last_col != last_col)
500
+ {
501
+ document->last_line = last_line;
502
+ document->last_col = last_col;
503
+
504
+ VALUE err_obj = ruby_create_error(self, r_last_line, r_last_col, rb_iv_get(self, "@xpath"), erno, format, ap);
505
+
506
+ VALUE expected = rb_str_new2("");
507
+
508
+ if (erno & ERBIT_RNV)
509
+ {
510
+ if (document->nexp)
511
+ {
512
+ int req = 2, i = 0;
513
+ char *s;
514
+ while (req--)
515
+ {
516
+ rnx_expected(rnv, document->previous, req);
517
+ if (i == rnv->rnx_n_exp)
518
+ continue;
519
+ if (rnv->rnx_n_exp > document->nexp)
520
+ break;
521
+
522
+ expected = rb_str_cat2(expected, (char *)(req ? "required:\n" : "allowed:\n"));
523
+ VALUE expected_arr = rb_ary_new2(0);
524
+
525
+ for (; i != rnv->rnx_n_exp; ++i)
526
+ {
527
+ s = rnx_p2str(rnv, rnv->rnx_exp[i]);
528
+ expected = rb_str_cat2(expected, "\t");
529
+ expected = rb_str_cat2(expected, s);
530
+ expected = rb_str_cat2(expected, "\n");
531
+ m_free(s);
532
+
533
+ rb_ary_push(expected_arr, ruby_p2arr(rnv, rnv->rnx_exp[i]));
534
+ }
535
+
536
+ if (req)
537
+ rb_iv_set(err_obj, "@required", expected_arr);
538
+ else
539
+ rb_iv_set(err_obj, "@allowed", expected_arr);
540
+ }
541
+ }
542
+ }
543
+ rb_iv_set(err_obj, "@original_expected", expected);
544
+
545
+ rb_ary_push(errors, err_obj);
546
+ }
547
+ }
548
+ }