ruby_rnv 0.2.4 → 0.4.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a97a5b35a39aa2ad603660b81b9c13e04375dafbc9f537fec0720357befd53f8
4
- data.tar.gz: 54dff4be913ec5e3e356cb43c5d58a936aa6aa76f38212212a19f3057875f22c
3
+ metadata.gz: 899300861f1a2b315f879d451a7a5ee472302fbdac26ea775a2e56e09793d98c
4
+ data.tar.gz: 4f2139ddde96c34a077e124600bb7cbbb0e98ef5db5fe5c57066bdcc8fd4c089
5
5
  SHA512:
6
- metadata.gz: bacdd196d95d59883413268ab7dc70d68bd39d4d93876ca156687aceabd7d76cd917a09dbeea4537a3f3c96cbc883bd6f7cd35bf152ac0c421e6e9183f14c2a9
7
- data.tar.gz: c43c097908014a8dc61fedab76ab407012077ec471fdc256aeca28d8261e3c90a4678f50a7b4308aa66efd96c008e1eb2e86f6fafe3ef1418b433b0da74a146c
6
+ metadata.gz: c9660b568d0a4fe092080bb095fd80125540ece28c669ecae73faa9391567a337fcd8799702b29bdcecd022b9613f76c3d9e6013f3c289000a5a98950bd67860
7
+ data.tar.gz: 63924d0755a95489733c62ccde564260750dcfea5e0a366e26d6663178b00e47d6ee095f18b8cee293c7c4eba457746a86cb9eedb696c7e63321449cbbf89536
data/ext/rnv/extconf.rb CHANGED
@@ -3,7 +3,7 @@ require 'mkmf'
3
3
  CONFIG['warnflags'].gsub!(/-W.* /, '')
4
4
 
5
5
  $srcs = %w{src/rn.c src/rnc.c src/rnd.c src/rnl.c src/rnv.c src/rnx.c src/drv.c src/ary.c src/xsd.c src/xsd_tm.c
6
- src/sc.c src/u.c src/ht.c src/er.c src/xmlc.c src/s.c src/m.c src/rx.c ruby_rnv.c}
6
+ src/sc.c src/u.c src/ht.c src/er.c src/xmlc.c src/s.c src/m.c src/rx.c ruby_rnv_err.c ruby_rnv.c}
7
7
 
8
8
  $INCFLAGS << " -I$(srcdir)/src"
9
9
 
data/ext/rnv/ruby_rnv.c CHANGED
@@ -1,423 +1,40 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include <stdarg.h>
4
- #include <fcntl.h> /*open,close*/
5
- #include <sys/types.h>
6
- #include <unistd.h> /*open,read,close*/
7
- #include <string.h> /*strerror*/
8
- #include <errno.h>
9
- #include <assert.h>
10
-
11
- #include "src/m.h"
12
- #include "src/s.h"
13
- #include "src/erbit.h"
14
- #include "src/drv.h"
15
- #include "src/rnl.h"
16
- #include "src/rnv.h"
17
- #include "src/rnx.h"
18
- #include "src/ll.h"
19
- #include "src/er.h"
20
- #include "src/erbit.h"
21
- #include "src/rnc.h"
22
- #include "src/rnd.h"
23
- #include "src/rx.h"
24
- #include "src/xsd.h"
25
-
26
- #include <ruby.h>
27
- #include <ruby/io.h>
1
+ #include "ruby_rnv.h"
28
2
 
29
3
  #define LEN_T XCL_LEN_T
30
4
  #define LIM_T XCL_LIM_T
31
5
 
32
- typedef struct document
33
- {
34
- char *fn;
35
- int start;
36
- int current;
37
- int previous;
38
- int lastline;
39
- int lastcol;
40
- int level;
41
- int opened;
42
- int ok;
43
- char *text;
44
- int len_txt;
45
- int n_txt;
46
- int mixed;
47
- int nexp;
48
-
49
- rnv_t *rnv;
50
- rn_st_t *rn_st;
51
- rnc_st_t *rnc_st;
52
- rnx_st_t *rnx_st;
53
- drv_st_t *drv_st;
54
- rx_st_t *rx_st;
55
- rnd_st_t *rnd_st;
56
-
57
- } document_t;
58
-
59
- VALUE RNV;
60
-
61
- // convert error code to symbol
62
- ID errno_to_id(int erno)
63
- {
64
- ID id;
65
- switch (erno)
66
- {
67
- case (ERBIT_RNC | RNC_ER_IO):
68
- id = rb_intern("rnc_er_io");
69
- break;
70
- case (ERBIT_RNC | RNC_ER_UTF):
71
- id = rb_intern("rnc_er_urf");
72
- break;
73
- case (ERBIT_RNC | RNC_ER_XESC):
74
- id = rb_intern("rnc_er_xesc");
75
- break;
76
- case (ERBIT_RNC | RNC_ER_LEXP):
77
- id = rb_intern("rnc_er_lexp");
78
- break;
79
- case (ERBIT_RNC | RNC_ER_LLIT):
80
- id = rb_intern("rnc_er_llit");
81
- break;
82
- case (ERBIT_RNC | RNC_ER_LILL):
83
- id = rb_intern("rnc_er_lill");
84
- break;
85
- case (ERBIT_RNC | RNC_ER_SEXP):
86
- id = rb_intern("rnc_er_sexp");
87
- break;
88
- case (ERBIT_RNC | RNC_ER_SILL):
89
- id = rb_intern("rnc_er_still");
90
- break;
91
- case (ERBIT_RNC | RNC_ER_NOTGR):
92
- id = rb_intern("rnc_er_notgr");
93
- break;
94
- case (ERBIT_RNC | RNC_ER_EXT):
95
- id = rb_intern("rnc_er_ext");
96
- break;
97
- case (ERBIT_RNC | RNC_ER_DUPNS):
98
- id = rb_intern("rnc_er_dupns");
99
- break;
100
- case (ERBIT_RNC | RNC_ER_DUPDT):
101
- id = rb_intern("rnc_er_dupdt");
102
- break;
103
- case (ERBIT_RNC | RNC_ER_DFLTNS):
104
- id = rb_intern("rnc_er_dfltns");
105
- break;
106
- case (ERBIT_RNC | RNC_ER_DFLTDT):
107
- id = rb_intern("rnc_er_dfltdt");
108
- break;
109
- case (ERBIT_RNC | RNC_ER_NONS):
110
- id = rb_intern("rnc_er_nons");
111
- break;
112
- case (ERBIT_RNC | RNC_ER_NODT):
113
- id = rb_intern("rnc_er_nodt");
114
- break;
115
- case (ERBIT_RNC | RNC_ER_NCEX):
116
- id = rb_intern("rnc_er_ncex");
117
- break;
118
- case (ERBIT_RNC | RNC_ER_2HEADS):
119
- id = rb_intern("rnc_er_2heads");
120
- break;
121
- case (ERBIT_RNC | RNC_ER_COMBINE):
122
- id = rb_intern("rnc_er_combine");
123
- break;
124
- case (ERBIT_RNC | RNC_ER_OVRIDE):
125
- id = rb_intern("rnc_er_ovride");
126
- break;
127
- case (ERBIT_RNC | RNC_ER_EXPT):
128
- id = rb_intern("rnc_er_excpt");
129
- break;
130
- case (ERBIT_RNC | RNC_ER_INCONT):
131
- id = rb_intern("rnc_er_incont");
132
- break;
133
- case (ERBIT_RNC | RNC_ER_NOSTART):
134
- id = rb_intern("rnc_er_nostart");
135
- break;
136
- case (ERBIT_RNC | RNC_ER_UNDEF):
137
- id = rb_intern("rnc_er_undef");
138
- break;
139
-
140
- case (ERBIT_RND | RND_ER_LOOPST):
141
- id = rb_intern("rnd_er_loopst");
142
- break;
143
- case (ERBIT_RND | RND_ER_LOOPEL):
144
- id = rb_intern("rnd_er_loopel");
145
- break;
146
- case (ERBIT_RND | RND_ER_CTYPE):
147
- id = rb_intern("rnd_er_ctype");
148
- break;
149
- case (ERBIT_RND | RND_ER_BADSTART):
150
- id = rb_intern("rnd_er_badstart");
151
- break;
152
- case (ERBIT_RND | RND_ER_BADMORE):
153
- id = rb_intern("rnd_er_badmore");
154
- break;
155
- case (ERBIT_RND | RND_ER_BADEXPT):
156
- id = rb_intern("rnd_er_badexpt");
157
- break;
158
- case (ERBIT_RND | RND_ER_BADLIST):
159
- id = rb_intern("rnd_er_badlist");
160
- break;
161
- case (ERBIT_RND | RND_ER_BADATTR):
162
- id = rb_intern("rnd_er_badattr");
163
- break;
164
-
165
- case (ERBIT_RX | RX_ER_BADCH):
166
- id = rb_intern("rx_er_badch");
167
- break;
168
- case (ERBIT_RX | RX_ER_UNFIN):
169
- id = rb_intern("rx_er_unfin");
170
- break;
171
- case (ERBIT_RX | RX_ER_NOLSQ):
172
- id = rb_intern("rx_er_nolsq");
173
- break;
174
- case (ERBIT_RX | RX_ER_NORSQ):
175
- id = rb_intern("rx_er_norsq");
176
- break;
177
- case (ERBIT_RX | RX_ER_NOLCU):
178
- id = rb_intern("rx_er_nolcu");
179
- break;
180
- case (ERBIT_RX | RX_ER_NORCU):
181
- id = rb_intern("rx_er_norcu");
182
- break;
183
- case (ERBIT_RX | RX_ER_NOLPA):
184
- id = rb_intern("rx_er_nolpa");
185
- break;
186
- case (ERBIT_RX | RX_ER_NORPA):
187
- id = rb_intern("rx_er_norpa");
188
- break;
189
- case (ERBIT_RX | RX_ER_BADCL):
190
- id = rb_intern("rx_er_badcl");
191
- break;
192
- case (ERBIT_RX | RX_ER_NODGT):
193
- id = rb_intern("rx_er_nodgt");
194
- break;
195
- case (ERBIT_RX | RX_ER_DNUOB):
196
- id = rb_intern("rx_er_dnuob");
197
- break;
198
- case (ERBIT_RX | RX_ER_NOTRC):
199
- id = rb_intern("rx_er_notrc");
200
- break;
201
-
202
- case (ERBIT_XSD | XSD_ER_TYP):
203
- id = rb_intern("xsd_er_typ");
204
- break;
205
- case (ERBIT_XSD | XSD_ER_PAR):
206
- id = rb_intern("xsd_er_par");
207
- break;
208
- case (ERBIT_XSD | XSD_ER_PARVAL):
209
- id = rb_intern("xsd_er_parval");
210
- break;
211
- case (ERBIT_XSD | XSD_ER_VAL):
212
- id = rb_intern("xsd_er_val");
213
- break;
214
- case (ERBIT_XSD | XSD_ER_NPAT):
215
- id = rb_intern("xsd_er_npat");
216
- break;
217
- case (ERBIT_XSD | XSD_ER_WS):
218
- id = rb_intern("xsd_er_ws");
219
- break;
220
- case (ERBIT_XSD | XSD_ER_ENUM):
221
- id = rb_intern("xsd_er_enum");
222
- break;
223
-
224
- case (ERBIT_DRV | DRV_ER_NODTL):
225
- id = rb_intern("drv_er_nodtl");
226
- break;
227
-
228
- case (ERBIT_RNV | RNV_ER_ELEM):
229
- id = rb_intern("rnv_er_elem");
230
- break;
231
- case (ERBIT_RNV | RNV_ER_AKEY):
232
- id = rb_intern("rnv_er_akey");
233
- break;
234
- case (ERBIT_RNV | RNV_ER_AVAL):
235
- id = rb_intern("rnv_er_aval");
236
- break;
237
- case (ERBIT_RNV | RNV_ER_EMIS):
238
- id = rb_intern("rnv_er_emis");
239
- break;
240
- case (ERBIT_RNV | RNV_ER_AMIS):
241
- id = rb_intern("rnv_er_amis");
242
- break;
243
- case (ERBIT_RNV | RNV_ER_UFIN):
244
- id = rb_intern("rnv_er_ufin");
245
- break;
246
- case (ERBIT_RNV | RNV_ER_TEXT):
247
- id = rb_intern("rnv_er_text");
248
- break;
249
- case (ERBIT_RNV | RNV_ER_NOTX):
250
- id = rb_intern("rnv_er_notx");
251
- break;
252
-
253
- default:
254
- id = rb_intern("unknown");
255
- break;
256
- }
257
- return id;
258
- }
6
+ VALUE RNV, SchemaNotLoaded, Error, DataTypeLibrary, Document;
7
+
8
+ extern int ruby_verror_handler(void *data, int erno, char *format, va_list ap);
259
9
 
260
- int ruby_verror_handler(rnv_t *rnv, int erno, char *format, va_list ap)
10
+ VALUE rb_datatype_push_error(VALUE self, VALUE r_msg)
261
11
  {
262
- VALUE self = (VALUE)rnv->user_data;
263
12
  document_t *document;
13
+ VALUE r_doc = rb_iv_get(self, "@document");
14
+ Data_Get_Struct(r_doc, document_t, document);
264
15
 
265
- Data_Get_Struct(self, document_t, document);
266
-
267
- rnx_st_t *rnx_st = document->rnx_st;
268
-
269
- VALUE errors = rb_iv_get(self, "@errors");
16
+ Check_Type(r_msg, T_STRING);
270
17
 
271
- VALUE error_array = rb_ary_new2(2);
272
- VALUE error_str = rb_vsprintf(format, ap);
273
- VALUE error_erno = ID2SYM(errno_to_id(erno));
18
+ if(document->rnv->verror_handler)
19
+ document->rnv->verror_handler((void *)r_doc, ERBIT_DTL, RSTRING_PTR(r_msg), NULL);
274
20
 
275
- // lazyly strip with ruby
276
- rb_funcall(error_str, rb_intern("strip!"), 0);
277
-
278
- VALUE err_class = rb_const_get(RNV, rb_intern("Error"));
279
- VALUE err_obj = rb_class_new_instance(0, NULL, err_class);
280
- rb_iv_set(err_obj, "@document", self);
281
- rb_iv_set(err_obj, "@code", error_erno);
282
- rb_iv_set(err_obj, "@message", error_str);
283
- rb_iv_set(err_obj, "@line", rb_iv_get(self, "@last_line"));
284
- rb_iv_set(err_obj, "@col", rb_iv_get(self, "@last_col"));
285
-
286
- VALUE expected = rb_str_new2("");
287
- if (erno & ERBIT_RNV)
288
- {
289
- if (document->nexp)
290
- {
291
- int req = 2, i = 0;
292
- char *s;
293
- while (req--)
294
- {
295
- rnx_expected(rnv, rnx_st, document->previous, req);
296
- if (i == rnv->rnx_n_exp)
297
- continue;
298
- if (rnv->rnx_n_exp > document->nexp)
299
- break;
300
-
301
- expected = rb_str_cat2(expected, (char *)(req ? "required:\n" : "allowed:\n"));
302
-
303
- for (; i != rnv->rnx_n_exp; ++i)
304
- {
305
- s = rnx_p2str(rnv, rnv->rnx_exp[i]);
306
- expected = rb_str_cat2(expected, "\t");
307
- expected = rb_str_cat2(expected, s);
308
- expected = rb_str_cat2(expected, "\n");
309
- m_free(s);
310
- }
311
- }
312
- }
313
- }
314
-
315
- rb_iv_set(err_obj, "@expected", expected);
316
-
317
- rb_ary_push(errors, err_obj);
318
- }
319
-
320
- /*
321
- * @return [String]
322
- */
323
- VALUE rb_error_inspect(VALUE self)
324
- {
325
- VALUE code = rb_iv_get(self, "@code");
326
- VALUE message = rb_iv_get(self, "@message");
327
- VALUE expected = rb_iv_get(self, "@expected");
328
- VALUE line = rb_iv_get(self, "@line");
329
- VALUE col = rb_iv_get(self, "@col");
330
-
331
- VALUE ret = rb_str_new2("#<RNV::Error ");
332
- ret = rb_str_cat2(ret, "code: :");
333
- ret = rb_str_append(ret, rb_obj_as_string(code));
334
- ret = rb_str_cat2(ret, ", ");
335
- ret = rb_str_cat2(ret, "message: '");
336
- ret = rb_str_append(ret, message);
337
- ret = rb_str_cat2(ret, "', ");
338
- ret = rb_str_cat2(ret, "expected: '");
339
- ret = rb_str_append(ret, expected);
340
- ret = rb_str_cat2(ret, "', ");
341
- ret = rb_str_cat2(ret, "line: ");
342
- ret = rb_str_append(ret, rb_obj_as_string(line));
343
- ret = rb_str_cat2(ret, ", ");
344
- ret = rb_str_cat2(ret, "col: ");
345
- ret = rb_str_append(ret, rb_obj_as_string(col));
346
- ret = rb_str_cat2(ret, ">");
347
- return ret;
21
+ return Qnil;
348
22
  }
349
23
 
350
- /*
351
- * @return [String]
352
- */
353
- VALUE rb_error_to_s(VALUE self)
24
+ void document_free(document_t *document)
354
25
  {
355
- VALUE message = rb_iv_get(self, "@message");
356
- VALUE expected = rb_iv_get(self, "@expected");
357
- VALUE line = rb_iv_get(self, "@line");
358
- VALUE col = rb_iv_get(self, "@col");
26
+ rnd_dispose(document->rnd_st);
27
+ rx_dispose(document->rx_st);
28
+ drv_dispose(document->drv_st);
359
29
 
360
- VALUE ret = rb_str_new2("");
30
+ rnc_dispose(document->rnc_st);
361
31
 
362
- ret = rb_str_append(ret, rb_obj_as_string(line));
363
- ret = rb_str_cat2(ret, ":");
364
- ret = rb_str_append(ret, rb_obj_as_string(col));
32
+ rn_dispose(document->rn_st);
365
33
 
366
- ret = rb_str_cat2(ret, ": error: ");
34
+ rnv_dispose(document->rnv);
367
35
 
368
- ret = rb_str_append(ret, message);
369
- ret = rb_str_cat2(ret, "\n");
370
- ret = rb_str_append(ret, expected);
371
-
372
- return ret;
373
- }
374
-
375
- void document_free(document_t *document)
376
- {
377
- // FIXME : introduce *_delete functions
378
- if (document->rnd_st->flat)
379
- free(document->rnd_st->flat);
380
- free(document->rnd_st);
381
-
382
- ht_dispose(&document->rx_st->ht_r);
383
- ht_dispose(&document->rx_st->ht_p);
384
- ht_dispose(&document->rx_st->ht_2);
385
- ht_dispose(&document->rx_st->ht_m);
386
- if (document->rx_st->regex)
387
- free(document->rx_st->regex);
388
- if (document->rx_st->pattern)
389
- free(document->rx_st->pattern);
390
- free(document->rx_st);
391
-
392
- if (document->drv_st->dtl)
393
- free(document->drv_st->dtl);
394
- ht_dispose(&document->drv_st->ht_m);
395
- free(document->drv_st);
396
-
397
- free(document->rnx_st);
398
-
399
- if (document->rnc_st->path)
400
- free(document->rnc_st->path);
401
- free(document->rnc_st);
402
-
403
- ht_dispose(&document->rn_st->ht_p);
404
- ht_dispose(&document->rn_st->ht_nc);
405
- ht_dispose(&document->rn_st->ht_s);
406
-
407
- free(document->rn_st);
408
-
409
- if (document->rnv->rn_pattern)
410
- free(document->rnv->rn_pattern);
411
- if (document->rnv->rn_nameclass)
412
- free(document->rnv->rn_nameclass);
413
- if (document->rnv->rn_string)
414
- free(document->rnv->rn_string);
415
- if (document->rnv->rnx_exp)
416
- free(document->rnv->rnx_exp);
417
-
418
- free(document->rnv);
419
-
420
- free(document->text);
36
+ if (document->text)
37
+ free(document->text);
421
38
 
422
39
  ruby_xfree(document);
423
40
  }
@@ -426,13 +43,12 @@ VALUE rb_document_alloc(VALUE klass)
426
43
  {
427
44
  document_t *document = ruby_xmalloc(sizeof(document_t));
428
45
 
429
- document->rnv = malloc(sizeof(rnv_t));
430
- document->rn_st = malloc(sizeof(rn_st_t));
431
- document->rnc_st = malloc(sizeof(rnc_st_t));
432
- document->rnx_st = malloc(sizeof(rnx_st_t));
433
- document->drv_st = malloc(sizeof(drv_st_t));
434
- document->rx_st = malloc(sizeof(rx_st_t));
435
- document->rnd_st = malloc(sizeof(rnd_st_t));
46
+ document->rnv = calloc(1, sizeof(rnv_t));
47
+ document->rn_st = calloc(1, sizeof(rn_st_t));
48
+ document->rnc_st = calloc(1, sizeof(rnc_st_t));
49
+ document->drv_st = calloc(1, sizeof(drv_st_t));
50
+ document->rx_st = calloc(1, sizeof(rx_st_t));
51
+ document->rnd_st = calloc(1, sizeof(rnd_st_t));
436
52
 
437
53
  return Data_Wrap_Struct(klass, NULL, document_free, document);
438
54
  }
@@ -442,17 +58,31 @@ VALUE rb_document_init(VALUE self)
442
58
  document_t *document;
443
59
  Data_Get_Struct(self, document_t, document);
444
60
 
445
- rnl_init(document->rnv, document->rn_st, document->rnc_st, document->rnd_st);
61
+ document->rnv->verror_handler = &ruby_verror_handler;
62
+ document->rnv->user_data = (void *)self;
63
+
64
+ rnl_init(document->rnv, document->rnc_st, document->rn_st, document->rnd_st);
446
65
  rnv_init(document->rnv, document->drv_st, document->rn_st, document->rx_st);
447
- rnx_init(document->rnv, document->rnx_st);
66
+ rnx_init(document->rnv);
448
67
 
449
68
  document->opened = document->ok = 0;
450
- document->rnv->user_data = (void *)self;
451
- document->rnv->verror_handler = &ruby_verror_handler;
69
+
452
70
  document->nexp = 16; /* maximum number of candidates to display */
71
+ document->text = NULL;
453
72
 
454
73
  rb_iv_set(self, "@errors", rb_ary_new2(0));
455
74
 
75
+ rb_iv_set(self, "@libraries", rb_hash_new());
76
+
77
+ document->last_line = -1;
78
+ document->last_col = -1;
79
+
80
+ rb_iv_set(self, "@last_line", INT2NUM(-1));
81
+ rb_iv_set(self, "@last_col", INT2NUM(-1));
82
+
83
+ //document->rx_st->rx_compact = 1;
84
+ //document->drv_st->drv_compact = 1;
85
+
456
86
  return self;
457
87
  }
458
88
 
@@ -542,6 +172,63 @@ VALUE rb_document_valid(VALUE self)
542
172
  return Qfalse;
543
173
  }
544
174
 
175
+ static int rb_dtl_equal(rnv_t *rnv, rn_st_t *rn_st, rx_st_t *rx_st, int uri, char *typ, char *val, char *s, int n)
176
+ {
177
+ VALUE self = (VALUE)rnv->user_data;
178
+ VALUE libraries = rb_iv_get(self, "@libraries");
179
+ VALUE lib = rb_hash_aref(libraries, INT2FIX(uri));
180
+
181
+ // do we need n here, do s always null terminated ?
182
+ VALUE ret = rb_funcall(lib, rb_intern("equal"), 3,
183
+ rb_str_new2(typ), rb_str_new2(val), rb_str_new2(s));
184
+
185
+ return RTEST(ret);
186
+ }
187
+
188
+ static int rb_dtl_allows(rnv_t *rnv, rn_st_t *rn_st, rx_st_t *rx_st, int uri, char *typ, char *ps, char *s, int n)
189
+ {
190
+ VALUE self = (VALUE)rnv->user_data;
191
+ VALUE libraries = rb_iv_get(self, "@libraries");
192
+ VALUE lib = rb_hash_aref(libraries, INT2FIX(uri));
193
+
194
+ // do we need n here, do s always null terminated ?
195
+ VALUE ret = rb_funcall(lib, rb_intern("allows"), 3,
196
+ rb_str_new2(typ), rb_str_new2(ps), rb_str_new2(s));
197
+
198
+ return RTEST(ret);
199
+ }
200
+
201
+ /*
202
+ * add a new datatype library
203
+ * @see https://www.oasis-open.org/committees/relax-ng/spec-20010811.html#IDA1I1R
204
+ * @param [String] r_ns unique ns URL for this datatype
205
+ * @param [RNV::DataTypeLibrary] r_cb_obj
206
+ * @return [nil]
207
+ */
208
+ VALUE rb_document_add_dtl(VALUE self, VALUE r_ns, VALUE r_cb_obj)
209
+ {
210
+ document_t *document;
211
+ Data_Get_Struct(self, document_t, document);
212
+
213
+ if (document->opened)
214
+ {
215
+ Check_Type(r_ns, T_STRING);
216
+
217
+ char *suri = RSTRING_PTR(r_ns);
218
+
219
+ drv_add_dtl(document->rnv, document->drv_st, document->rn_st, suri, &rb_dtl_equal, &rb_dtl_allows);
220
+
221
+ int uri = document->drv_st->dtl[document->drv_st->n_dtl - 1].uri;
222
+
223
+ VALUE libraries = rb_iv_get(self, "@libraries");
224
+
225
+ rb_iv_set(r_cb_obj, "@document", self);
226
+
227
+ rb_hash_aset(libraries, INT2FIX(uri), r_cb_obj);
228
+ }
229
+ return Qnil;
230
+ }
231
+
545
232
  static void flush_text(document_t *document)
546
233
  {
547
234
  document->ok = rnv_text(document->rnv, document->drv_st, document->rn_st, document->rx_st,
@@ -551,7 +238,7 @@ static void flush_text(document_t *document)
551
238
  }
552
239
 
553
240
  /*
554
- * begin a new document
241
+ * begin parsing a new document
555
242
  * @return [nil]
556
243
  */
557
244
  VALUE rb_document_begin(VALUE self)
@@ -559,11 +246,22 @@ VALUE rb_document_begin(VALUE self)
559
246
  document_t *document;
560
247
  Data_Get_Struct(self, document_t, document);
561
248
 
249
+ if (!document->opened)
250
+ rb_raise(SchemaNotLoaded, "schema was not loaded correctly");
251
+
252
+ // reset errors
253
+ rb_iv_set(self, "@errors", rb_ary_new2(0));
254
+
562
255
  m_free(document->text);
563
256
  document->text = (char *)m_alloc(document->len_txt = LEN_T, sizeof(char));
564
257
 
565
258
  document->ok = document->current = document->previous = document->start;
566
259
 
260
+ document->last_line = 0;
261
+ document->last_col = 0;
262
+
263
+ document->level = 0;
264
+
567
265
  document->text[0] = '\0';
568
266
  document->n_txt = 0;
569
267
  document->mixed = 0;
@@ -574,14 +272,17 @@ VALUE rb_document_begin(VALUE self)
574
272
  /*
575
273
  * to be called by SAX characters handler
576
274
  * @param [String] r_str characters
577
- * @return [Integer]
275
+ * @return [Boolean]
578
276
  */
579
277
  VALUE rb_document_characters(VALUE self, VALUE r_str)
580
278
  {
581
279
  document_t *document;
582
280
  Data_Get_Struct(self, document_t, document);
583
281
 
584
- if (document->opened && document->current != document->rnv->rn_notAllowed)
282
+ if (!document->opened)
283
+ rb_raise(SchemaNotLoaded, "schema was not loaded correctly");
284
+
285
+ if (document->current != document->rnv->rn_notAllowed)
585
286
  {
586
287
  Check_Type(r_str, T_STRING);
587
288
  char *s = RSTRING_PTR(r_str);
@@ -602,21 +303,24 @@ VALUE rb_document_characters(VALUE self, VALUE r_str)
602
303
  document->text[document->n_txt] = '\0'; /* '\0' guarantees that the text is bounded, and strto[ld] work for data */
603
304
  }
604
305
 
605
- return INT2NUM(document->ok);
306
+ return RTEST(document->ok);
606
307
  }
607
308
 
608
309
  /*
609
310
  * to be called by SAX start tag handler
610
311
  * @param [String] r_name tag name, must be in the form 'NS_URI:TAG_NAME'
611
- * @param [Array<String>] r_attrs flattened array of tag attributes in the form ['NS_URI:ATTR_NAME','ATTR_VALUE']
612
- * @return [Integer]
312
+ * @param [Array<Array<String>>] r_attrs flattened array of tag attributes in the form [['NS_URI:ATTR_NAME','ATTR_VALUE']]
313
+ * @return [Boolean]
613
314
  */
614
315
  VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
615
316
  {
616
317
  document_t *document;
617
318
  Data_Get_Struct(self, document_t, document);
618
319
 
619
- if (document->opened && document->current != document->rnv->rn_notAllowed)
320
+ if (!document->opened)
321
+ rb_raise(SchemaNotLoaded, "schema was not loaded correctly");
322
+
323
+ if (document->current != document->rnv->rn_notAllowed)
620
324
  {
621
325
  int i;
622
326
  char *name;
@@ -626,20 +330,22 @@ VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
626
330
  name = RSTRING_PTR(r_name);
627
331
 
628
332
  Check_Type(r_attrs, T_ARRAY);
629
- unsigned int attrs_len = RARRAY_LEN(r_attrs);
333
+
334
+ // lazyly flatten with ruby
335
+ VALUE r_flat_attrs = rb_funcall(r_attrs, rb_intern("flatten"), 0);
336
+ unsigned int attrs_len = RARRAY_LEN(r_flat_attrs);
630
337
 
631
338
  attrs = malloc(sizeof(char *) * (attrs_len + 1));
632
339
 
633
340
  for (i = 0; i < attrs_len; i++)
634
341
  {
635
- attrs[i] = RSTRING_PTR(rb_ary_entry(r_attrs, i));
342
+ attrs[i] = RSTRING_PTR(rb_ary_entry(r_flat_attrs, i));
636
343
  }
637
344
  attrs[attrs_len] = 0; // zero terminated
638
345
 
639
346
  document->mixed = 1;
640
347
 
641
348
  flush_text(document);
642
- //printf("RNV START %d/%d %s %d\n", current, previous, name, attrs_len);
643
349
  document->ok = rnv_start_tag(document->rnv, document->drv_st, document->rn_st, document->rx_st,
644
350
  &document->current, &document->previous, (char *)name, (char **)attrs) &&
645
351
  document->ok;
@@ -647,21 +353,28 @@ VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
647
353
  document->mixed = 0;
648
354
  free(attrs);
649
355
  }
356
+ else
357
+ {
358
+ ++document->level;
359
+ }
650
360
 
651
- return INT2NUM(document->ok);
361
+ return RTEST(document->ok);
652
362
  }
653
363
 
654
364
  /*
655
365
  * to be called by SAX end tag handler
656
366
  * @param [String] r_name tag name, must be in the form 'NS_URI:TAG_NAME'
657
- * @return [Integer]
367
+ * @return [Boolean]
658
368
  */
659
369
  VALUE rb_document_end_tag(VALUE self, VALUE r_name)
660
370
  {
661
371
  document_t *document;
662
372
  Data_Get_Struct(self, document_t, document);
663
373
 
664
- if (document->opened && document->current != document->rnv->rn_notAllowed)
374
+ if (!document->opened)
375
+ rb_raise(SchemaNotLoaded, "schema was not loaded correctly");
376
+
377
+ if (document->current != document->rnv->rn_notAllowed)
665
378
  {
666
379
  char *name;
667
380
 
@@ -670,15 +383,21 @@ VALUE rb_document_end_tag(VALUE self, VALUE r_name)
670
383
 
671
384
  flush_text(document);
672
385
 
673
- //printf("RNV END %d/%d %s\n", current, previous, name);
674
386
  document->ok = rnv_end_tag(document->rnv, document->drv_st, document->rn_st,
675
387
  &document->current, &document->previous, (char *)name) &&
676
388
  document->ok;
677
389
 
678
390
  document->mixed = 1;
679
391
  }
392
+ else
393
+ {
394
+ if (document->level == 0)
395
+ document->current = document->previous;
396
+ else
397
+ --document->level;
398
+ }
680
399
 
681
- return INT2NUM(document->ok);
400
+ return RTEST(document->ok);
682
401
  }
683
402
 
684
403
  // The initialization method for this module
@@ -686,21 +405,15 @@ void Init_rnv()
686
405
  {
687
406
  RNV = rb_define_module("RNV");
688
407
 
689
- VALUE Error = rb_define_class_under(RNV, "Error", rb_cObject);
408
+ SchemaNotLoaded = rb_define_class_under(RNV, "SchemaNotLoaded", rb_eStandardError);
690
409
 
691
- rb_define_method(Error, "inspect", rb_error_inspect, 0);
692
- rb_define_method(Error, "to_s", rb_error_to_s, 0);
410
+ Error = rb_define_class_under(RNV, "Error", rb_cObject);
693
411
 
694
412
  /*
695
413
  * error symbol code
696
414
  * @return [Symbol]
697
415
  */
698
416
  rb_define_attr(Error, "code", 1, 0);
699
- /*
700
- * error message
701
- * @return [String]
702
- */
703
- rb_define_attr(Error, "message", 1, 0);
704
417
  /*
705
418
  * error line
706
419
  * @return [Integer]
@@ -712,7 +425,17 @@ void Init_rnv()
712
425
  */
713
426
  rb_define_attr(Error, "col", 1, 0);
714
427
 
715
- VALUE Document = rb_define_class_under(RNV, "Document", rb_cObject);
428
+ DataTypeLibrary = rb_define_class_under(RNV, "DataTypeLibrary", rb_cObject);
429
+
430
+ /*
431
+ * document in which library is registered
432
+ * @return [RNV::Document]
433
+ */
434
+ rb_define_attr(DataTypeLibrary, "document", 1, 0);
435
+
436
+ rb_define_method(DataTypeLibrary, "push_error", rb_datatype_push_error, 1);
437
+
438
+ Document = rb_define_class_under(RNV, "Document", rb_cObject);
716
439
 
717
440
  rb_define_alloc_func(Document, rb_document_alloc);
718
441
  rb_define_method(Document, "initialize", rb_document_init, 0);
@@ -721,6 +444,8 @@ void Init_rnv()
721
444
  rb_define_method(Document, "load_string", rb_document_load_string, 1);
722
445
  rb_define_method(Document, "valid?", rb_document_valid, 0);
723
446
 
447
+ rb_define_method(Document, "add_datatype_library", rb_document_add_dtl, 2);
448
+
724
449
  rb_define_method(Document, "start_document", rb_document_begin, 0);
725
450
  rb_define_method(Document, "start_tag", rb_document_start_tag, 2);
726
451
  rb_define_method(Document, "characters", rb_document_characters, 1);