ruby_rnv 0.2.3 → 0.4.1
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 +4 -4
- data/ext/rnv/extconf.rb +1 -1
- data/ext/rnv/ruby_rnv.c +177 -457
- data/ext/rnv/ruby_rnv.h +62 -0
- data/ext/rnv/ruby_rnv_err.c +545 -0
- data/ext/rnv/src/ary.c +1 -2
- data/ext/rnv/src/drv.c +75 -75
- data/ext/rnv/src/drv.h +12 -3
- data/ext/rnv/src/er.c +1 -1
- data/ext/rnv/src/er.h +1 -1
- data/ext/rnv/src/erbit.h +3 -0
- data/ext/rnv/src/rn.c +24 -26
- data/ext/rnv/src/rn.h +1 -1
- data/ext/rnv/src/rnc.c +28 -16
- data/ext/rnv/src/rnc.h +3 -23
- data/ext/rnv/src/rnd.c +24 -20
- data/ext/rnv/src/rnd.h +3 -2
- data/ext/rnv/src/rnl.c +24 -20
- data/ext/rnv/src/rnl.h +2 -3
- data/ext/rnv/src/rnv.c +20 -18
- data/ext/rnv/src/rnv.h +2 -2
- data/ext/rnv/src/rnx.c +15 -17
- data/ext/rnv/src/rnx.h +2 -3
- data/ext/rnv/src/rx.c +44 -32
- data/ext/rnv/src/rx.h +7 -8
- data/ext/rnv/src/sc.c +5 -0
- data/ext/rnv/src/sc.h +1 -0
- data/ext/rnv/src/type.h +53 -29
- data/ext/rnv/src/xcl.c +24 -27
- data/ext/rnv/src/xsd.c +10 -23
- data/ext/rnv/src/xsd.h +1 -2
- data/lib/rnv.rb +3 -0
- data/lib/rnv/data_type_library.rb +21 -0
- data/lib/rnv/error.rb +102 -0
- data/lib/rnv/pre_processor.rb +25 -0
- data/lib/rnv/validator.rb +24 -11
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f815e167e18653e6820b447245834127448b9ac2b72c2f0228baefb40226007d
|
4
|
+
data.tar.gz: d192a9e1faa7e62c25caf68fca1beaeb7a77f706a85ecf50175f70c5e4dd45f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d53f3238103630b7617fe91850bd4ad930781981cc3d67cd8a5f1d9cfb4ff90d9de6463483e2ee054bce3cbeb19f6407edeb5dd91008b222a464a6bd7ab07d0
|
7
|
+
data.tar.gz: 3613bb75f3ef998a5a90af133fcbcc40b51a7bb983149bbcb8bae67e800a72c5a61978f26fb96aed8ec707d2ecbac2a4356fbe457382dbf85277be6638257074
|
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
|
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
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
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
|
-
|
266
|
-
|
267
|
-
rnx_st_t *rnx_st = document->rnx_st;
|
268
|
-
|
269
|
-
VALUE errors = rb_iv_get(self, "@errors");
|
270
|
-
|
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));
|
16
|
+
Check_Type(r_msg, T_STRING);
|
274
17
|
|
275
|
-
|
276
|
-
|
18
|
+
if(document->rnv->verror_handler)
|
19
|
+
document->rnv->verror_handler((void *)r_doc, ERBIT_DTL, RSTRING_PTR(r_msg), NULL);
|
277
20
|
|
278
|
-
|
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
|
-
|
356
|
-
|
357
|
-
|
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
|
-
|
30
|
+
rnc_dispose(document->rnc_st);
|
361
31
|
|
362
|
-
|
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
|
-
|
34
|
+
rnv_dispose(document->rnv);
|
367
35
|
|
368
|
-
|
369
|
-
|
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 =
|
430
|
-
document->rn_st =
|
431
|
-
document->rnc_st =
|
432
|
-
document->
|
433
|
-
document->
|
434
|
-
document->
|
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
|
-
|
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
|
66
|
+
rnx_init(document->rnv);
|
448
67
|
|
449
68
|
document->opened = document->ok = 0;
|
450
|
-
|
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
|
|
@@ -489,10 +119,11 @@ VALUE rb_document_load_string(VALUE self, VALUE r_str)
|
|
489
119
|
document->fn,
|
490
120
|
RSTRING_PTR(r_str), RSTRING_LEN(r_str));
|
491
121
|
|
492
|
-
document_load(document);
|
493
|
-
|
494
122
|
if (document->opened)
|
123
|
+
{
|
124
|
+
document_load(document);
|
495
125
|
return Qtrue;
|
126
|
+
}
|
496
127
|
else
|
497
128
|
return Qfalse;
|
498
129
|
}
|
@@ -507,27 +138,21 @@ VALUE rb_document_load_file(VALUE self, VALUE r_fn)
|
|
507
138
|
document_t *document;
|
508
139
|
Data_Get_Struct(self, document_t, document);
|
509
140
|
|
510
|
-
|
511
|
-
{
|
512
|
-
case T_STRING:
|
513
|
-
document->fn = RSTRING_PTR(r_fn);
|
514
|
-
|
515
|
-
document->opened = rnl_fn(document->rnv,
|
516
|
-
document->rnc_st,
|
517
|
-
document->rn_st,
|
518
|
-
document->rnd_st,
|
519
|
-
document->fn);
|
520
|
-
break;
|
521
|
-
case T_FILE: // TODO
|
522
|
-
default:
|
523
|
-
rb_raise(rb_eTypeError, "invalid argument");
|
524
|
-
break;
|
525
|
-
}
|
141
|
+
Check_Type(r_fn, T_STRING);
|
526
142
|
|
527
|
-
|
143
|
+
document->fn = RSTRING_PTR(r_fn);
|
144
|
+
|
145
|
+
document->opened = rnl_fn(document->rnv,
|
146
|
+
document->rnc_st,
|
147
|
+
document->rn_st,
|
148
|
+
document->rnd_st,
|
149
|
+
document->fn);
|
528
150
|
|
529
151
|
if (document->opened)
|
152
|
+
{
|
153
|
+
document_load(document);
|
530
154
|
return Qtrue;
|
155
|
+
}
|
531
156
|
else
|
532
157
|
return Qfalse;
|
533
158
|
}
|
@@ -547,6 +172,63 @@ VALUE rb_document_valid(VALUE self)
|
|
547
172
|
return Qfalse;
|
548
173
|
}
|
549
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
|
+
|
550
232
|
static void flush_text(document_t *document)
|
551
233
|
{
|
552
234
|
document->ok = rnv_text(document->rnv, document->drv_st, document->rn_st, document->rx_st,
|
@@ -556,7 +238,7 @@ static void flush_text(document_t *document)
|
|
556
238
|
}
|
557
239
|
|
558
240
|
/*
|
559
|
-
* begin a new document
|
241
|
+
* begin parsing a new document
|
560
242
|
* @return [nil]
|
561
243
|
*/
|
562
244
|
VALUE rb_document_begin(VALUE self)
|
@@ -564,11 +246,22 @@ VALUE rb_document_begin(VALUE self)
|
|
564
246
|
document_t *document;
|
565
247
|
Data_Get_Struct(self, document_t, document);
|
566
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
|
+
|
567
255
|
m_free(document->text);
|
568
256
|
document->text = (char *)m_alloc(document->len_txt = LEN_T, sizeof(char));
|
569
257
|
|
570
258
|
document->ok = document->current = document->previous = document->start;
|
571
259
|
|
260
|
+
document->last_line = 0;
|
261
|
+
document->last_col = 0;
|
262
|
+
|
263
|
+
document->level = 0;
|
264
|
+
|
572
265
|
document->text[0] = '\0';
|
573
266
|
document->n_txt = 0;
|
574
267
|
document->mixed = 0;
|
@@ -579,14 +272,17 @@ VALUE rb_document_begin(VALUE self)
|
|
579
272
|
/*
|
580
273
|
* to be called by SAX characters handler
|
581
274
|
* @param [String] r_str characters
|
582
|
-
* @return [
|
275
|
+
* @return [Boolean]
|
583
276
|
*/
|
584
277
|
VALUE rb_document_characters(VALUE self, VALUE r_str)
|
585
278
|
{
|
586
279
|
document_t *document;
|
587
280
|
Data_Get_Struct(self, document_t, document);
|
588
281
|
|
589
|
-
if (document->opened
|
282
|
+
if (!document->opened)
|
283
|
+
rb_raise(SchemaNotLoaded, "schema was not loaded correctly");
|
284
|
+
|
285
|
+
if (document->current != document->rnv->rn_notAllowed)
|
590
286
|
{
|
591
287
|
Check_Type(r_str, T_STRING);
|
592
288
|
char *s = RSTRING_PTR(r_str);
|
@@ -607,21 +303,24 @@ VALUE rb_document_characters(VALUE self, VALUE r_str)
|
|
607
303
|
document->text[document->n_txt] = '\0'; /* '\0' guarantees that the text is bounded, and strto[ld] work for data */
|
608
304
|
}
|
609
305
|
|
610
|
-
return
|
306
|
+
return RTEST(document->ok);
|
611
307
|
}
|
612
308
|
|
613
309
|
/*
|
614
310
|
* to be called by SAX start tag handler
|
615
311
|
* @param [String] r_name tag name, must be in the form 'NS_URI:TAG_NAME'
|
616
|
-
* @param [Array<String
|
617
|
-
* @return [
|
312
|
+
* @param [Array<Array<String>>] r_attrs flattened array of tag attributes in the form [['NS_URI:ATTR_NAME','ATTR_VALUE']]
|
313
|
+
* @return [Boolean]
|
618
314
|
*/
|
619
315
|
VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
|
620
316
|
{
|
621
317
|
document_t *document;
|
622
318
|
Data_Get_Struct(self, document_t, document);
|
623
319
|
|
624
|
-
if (document->opened
|
320
|
+
if (!document->opened)
|
321
|
+
rb_raise(SchemaNotLoaded, "schema was not loaded correctly");
|
322
|
+
|
323
|
+
if (document->current != document->rnv->rn_notAllowed)
|
625
324
|
{
|
626
325
|
int i;
|
627
326
|
char *name;
|
@@ -631,20 +330,22 @@ VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
|
|
631
330
|
name = RSTRING_PTR(r_name);
|
632
331
|
|
633
332
|
Check_Type(r_attrs, T_ARRAY);
|
634
|
-
|
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);
|
635
337
|
|
636
338
|
attrs = malloc(sizeof(char *) * (attrs_len + 1));
|
637
339
|
|
638
340
|
for (i = 0; i < attrs_len; i++)
|
639
341
|
{
|
640
|
-
attrs[i] = RSTRING_PTR(rb_ary_entry(
|
342
|
+
attrs[i] = RSTRING_PTR(rb_ary_entry(r_flat_attrs, i));
|
641
343
|
}
|
642
344
|
attrs[attrs_len] = 0; // zero terminated
|
643
345
|
|
644
346
|
document->mixed = 1;
|
645
347
|
|
646
348
|
flush_text(document);
|
647
|
-
//printf("RNV START %d/%d %s %d\n", current, previous, name, attrs_len);
|
648
349
|
document->ok = rnv_start_tag(document->rnv, document->drv_st, document->rn_st, document->rx_st,
|
649
350
|
&document->current, &document->previous, (char *)name, (char **)attrs) &&
|
650
351
|
document->ok;
|
@@ -652,21 +353,28 @@ VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
|
|
652
353
|
document->mixed = 0;
|
653
354
|
free(attrs);
|
654
355
|
}
|
356
|
+
else
|
357
|
+
{
|
358
|
+
++document->level;
|
359
|
+
}
|
655
360
|
|
656
|
-
return
|
361
|
+
return RTEST(document->ok);
|
657
362
|
}
|
658
363
|
|
659
364
|
/*
|
660
365
|
* to be called by SAX end tag handler
|
661
366
|
* @param [String] r_name tag name, must be in the form 'NS_URI:TAG_NAME'
|
662
|
-
* @return [
|
367
|
+
* @return [Boolean]
|
663
368
|
*/
|
664
369
|
VALUE rb_document_end_tag(VALUE self, VALUE r_name)
|
665
370
|
{
|
666
371
|
document_t *document;
|
667
372
|
Data_Get_Struct(self, document_t, document);
|
668
373
|
|
669
|
-
if (document->opened
|
374
|
+
if (!document->opened)
|
375
|
+
rb_raise(SchemaNotLoaded, "schema was not loaded correctly");
|
376
|
+
|
377
|
+
if (document->current != document->rnv->rn_notAllowed)
|
670
378
|
{
|
671
379
|
char *name;
|
672
380
|
|
@@ -675,15 +383,21 @@ VALUE rb_document_end_tag(VALUE self, VALUE r_name)
|
|
675
383
|
|
676
384
|
flush_text(document);
|
677
385
|
|
678
|
-
//printf("RNV END %d/%d %s\n", current, previous, name);
|
679
386
|
document->ok = rnv_end_tag(document->rnv, document->drv_st, document->rn_st,
|
680
387
|
&document->current, &document->previous, (char *)name) &&
|
681
388
|
document->ok;
|
682
389
|
|
683
390
|
document->mixed = 1;
|
684
391
|
}
|
392
|
+
else
|
393
|
+
{
|
394
|
+
if (document->level == 0)
|
395
|
+
document->current = document->previous;
|
396
|
+
else
|
397
|
+
--document->level;
|
398
|
+
}
|
685
399
|
|
686
|
-
return
|
400
|
+
return RTEST(document->ok);
|
687
401
|
}
|
688
402
|
|
689
403
|
// The initialization method for this module
|
@@ -691,21 +405,15 @@ void Init_rnv()
|
|
691
405
|
{
|
692
406
|
RNV = rb_define_module("RNV");
|
693
407
|
|
694
|
-
|
408
|
+
SchemaNotLoaded = rb_define_class_under(RNV, "SchemaNotLoaded", rb_eStandardError);
|
695
409
|
|
696
|
-
|
697
|
-
rb_define_method(Error, "to_s", rb_error_to_s, 0);
|
410
|
+
Error = rb_define_class_under(RNV, "Error", rb_cObject);
|
698
411
|
|
699
412
|
/*
|
700
413
|
* error symbol code
|
701
414
|
* @return [Symbol]
|
702
415
|
*/
|
703
416
|
rb_define_attr(Error, "code", 1, 0);
|
704
|
-
/*
|
705
|
-
* error message
|
706
|
-
* @return [String]
|
707
|
-
*/
|
708
|
-
rb_define_attr(Error, "message", 1, 0);
|
709
417
|
/*
|
710
418
|
* error line
|
711
419
|
* @return [Integer]
|
@@ -717,7 +425,17 @@ void Init_rnv()
|
|
717
425
|
*/
|
718
426
|
rb_define_attr(Error, "col", 1, 0);
|
719
427
|
|
720
|
-
|
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);
|
721
439
|
|
722
440
|
rb_define_alloc_func(Document, rb_document_alloc);
|
723
441
|
rb_define_method(Document, "initialize", rb_document_init, 0);
|
@@ -726,6 +444,8 @@ void Init_rnv()
|
|
726
444
|
rb_define_method(Document, "load_string", rb_document_load_string, 1);
|
727
445
|
rb_define_method(Document, "valid?", rb_document_valid, 0);
|
728
446
|
|
447
|
+
rb_define_method(Document, "add_datatype_library", rb_document_add_dtl, 2);
|
448
|
+
|
729
449
|
rb_define_method(Document, "start_document", rb_document_begin, 0);
|
730
450
|
rb_define_method(Document, "start_tag", rb_document_start_tag, 2);
|
731
451
|
rb_define_method(Document, "characters", rb_document_characters, 1);
|