ruby_rnv 0.2.2 → 0.4.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.
- checksums.yaml +4 -4
- data/ext/rnv/extconf.rb +1 -1
- data/ext/rnv/ruby_rnv.c +187 -460
- 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 +39 -0
- data/lib/rnv/pre_processor.rb +25 -0
- data/lib/rnv/validator.rb +18 -11
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f72e473e7924c7c3e215b53e08311afcf6781bb17a3df2842300661e86b35601
|
4
|
+
data.tar.gz: e513f2403d0ae91f35fde8f4b81b264a3ff16bb0a6be5f1dc80b17f3aa00ddcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0ce856ca07f203e0a0a4307943a113ff703e5a32031946e463496d485b49bafbeeb42a9057b3d697a92a00294c5d79c29b6bc7be62565dc75a910f16b4c1dbf
|
7
|
+
data.tar.gz: 3a5028a2bf2d558a9a7501336fe190a994dc867dd9eef83fcf9ce38ff481f6c1743f77e9d5f604ee9f3d07e95840bf7d79870b163fabf9f866e7c122e40f570b
|
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
|
|
@@ -470,7 +100,7 @@ static void document_load(document_t *document)
|
|
470
100
|
/*
|
471
101
|
* load schema from a buffer
|
472
102
|
* @param [String] r_str buffer
|
473
|
-
* @return [
|
103
|
+
* @return [Boolean]
|
474
104
|
*/
|
475
105
|
VALUE rb_document_load_string(VALUE self, VALUE r_str)
|
476
106
|
{
|
@@ -489,40 +119,42 @@ 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
|
-
|
493
|
-
|
122
|
+
if (document->opened)
|
123
|
+
{
|
124
|
+
document_load(document);
|
125
|
+
return Qtrue;
|
126
|
+
}
|
127
|
+
else
|
128
|
+
return Qfalse;
|
494
129
|
}
|
495
130
|
|
496
131
|
/*
|
497
132
|
* load schema from a file
|
498
133
|
* @param [String] r_fn filename
|
499
|
-
* @return [
|
134
|
+
* @return [Boolean]
|
500
135
|
*/
|
501
136
|
VALUE rb_document_load_file(VALUE self, VALUE r_fn)
|
502
137
|
{
|
503
138
|
document_t *document;
|
504
139
|
Data_Get_Struct(self, document_t, document);
|
505
140
|
|
506
|
-
|
141
|
+
Check_Type(r_fn, T_STRING);
|
142
|
+
|
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);
|
150
|
+
|
151
|
+
if (document->opened)
|
507
152
|
{
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
document->opened = rnl_fn(document->rnv,
|
512
|
-
document->rnc_st,
|
513
|
-
document->rn_st,
|
514
|
-
document->rnd_st,
|
515
|
-
document->fn);
|
516
|
-
|
517
|
-
break;
|
518
|
-
case T_FILE: // TODO
|
519
|
-
default:
|
520
|
-
rb_raise(rb_eTypeError, "invalid argument");
|
521
|
-
break;
|
153
|
+
document_load(document);
|
154
|
+
return Qtrue;
|
522
155
|
}
|
523
|
-
|
524
|
-
|
525
|
-
return INT2NUM(document->ok);
|
156
|
+
else
|
157
|
+
return Qfalse;
|
526
158
|
}
|
527
159
|
|
528
160
|
/*
|
@@ -540,6 +172,63 @@ VALUE rb_document_valid(VALUE self)
|
|
540
172
|
return Qfalse;
|
541
173
|
}
|
542
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
|
+
|
543
232
|
static void flush_text(document_t *document)
|
544
233
|
{
|
545
234
|
document->ok = rnv_text(document->rnv, document->drv_st, document->rn_st, document->rx_st,
|
@@ -549,7 +238,7 @@ static void flush_text(document_t *document)
|
|
549
238
|
}
|
550
239
|
|
551
240
|
/*
|
552
|
-
* begin a new document
|
241
|
+
* begin parsing a new document
|
553
242
|
* @return [nil]
|
554
243
|
*/
|
555
244
|
VALUE rb_document_begin(VALUE self)
|
@@ -557,11 +246,22 @@ VALUE rb_document_begin(VALUE self)
|
|
557
246
|
document_t *document;
|
558
247
|
Data_Get_Struct(self, document_t, document);
|
559
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
|
+
|
560
255
|
m_free(document->text);
|
561
256
|
document->text = (char *)m_alloc(document->len_txt = LEN_T, sizeof(char));
|
562
257
|
|
563
258
|
document->ok = document->current = document->previous = document->start;
|
564
259
|
|
260
|
+
document->last_line = 0;
|
261
|
+
document->last_col = 0;
|
262
|
+
|
263
|
+
document->level = 0;
|
264
|
+
|
565
265
|
document->text[0] = '\0';
|
566
266
|
document->n_txt = 0;
|
567
267
|
document->mixed = 0;
|
@@ -572,14 +272,17 @@ VALUE rb_document_begin(VALUE self)
|
|
572
272
|
/*
|
573
273
|
* to be called by SAX characters handler
|
574
274
|
* @param [String] r_str characters
|
575
|
-
* @return [
|
275
|
+
* @return [Boolean]
|
576
276
|
*/
|
577
277
|
VALUE rb_document_characters(VALUE self, VALUE r_str)
|
578
278
|
{
|
579
279
|
document_t *document;
|
580
280
|
Data_Get_Struct(self, document_t, document);
|
581
281
|
|
582
|
-
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)
|
583
286
|
{
|
584
287
|
Check_Type(r_str, T_STRING);
|
585
288
|
char *s = RSTRING_PTR(r_str);
|
@@ -600,21 +303,24 @@ VALUE rb_document_characters(VALUE self, VALUE r_str)
|
|
600
303
|
document->text[document->n_txt] = '\0'; /* '\0' guarantees that the text is bounded, and strto[ld] work for data */
|
601
304
|
}
|
602
305
|
|
603
|
-
return
|
306
|
+
return RTEST(document->ok);
|
604
307
|
}
|
605
308
|
|
606
309
|
/*
|
607
310
|
* to be called by SAX start tag handler
|
608
311
|
* @param [String] r_name tag name, must be in the form 'NS_URI:TAG_NAME'
|
609
|
-
* @param [Array<String
|
610
|
-
* @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]
|
611
314
|
*/
|
612
315
|
VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
|
613
316
|
{
|
614
317
|
document_t *document;
|
615
318
|
Data_Get_Struct(self, document_t, document);
|
616
319
|
|
617
|
-
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)
|
618
324
|
{
|
619
325
|
int i;
|
620
326
|
char *name;
|
@@ -624,20 +330,22 @@ VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
|
|
624
330
|
name = RSTRING_PTR(r_name);
|
625
331
|
|
626
332
|
Check_Type(r_attrs, T_ARRAY);
|
627
|
-
|
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);
|
628
337
|
|
629
338
|
attrs = malloc(sizeof(char *) * (attrs_len + 1));
|
630
339
|
|
631
340
|
for (i = 0; i < attrs_len; i++)
|
632
341
|
{
|
633
|
-
attrs[i] = RSTRING_PTR(rb_ary_entry(
|
342
|
+
attrs[i] = RSTRING_PTR(rb_ary_entry(r_flat_attrs, i));
|
634
343
|
}
|
635
344
|
attrs[attrs_len] = 0; // zero terminated
|
636
345
|
|
637
346
|
document->mixed = 1;
|
638
347
|
|
639
348
|
flush_text(document);
|
640
|
-
//printf("RNV START %d/%d %s %d\n", current, previous, name, attrs_len);
|
641
349
|
document->ok = rnv_start_tag(document->rnv, document->drv_st, document->rn_st, document->rx_st,
|
642
350
|
&document->current, &document->previous, (char *)name, (char **)attrs) &&
|
643
351
|
document->ok;
|
@@ -645,21 +353,28 @@ VALUE rb_document_start_tag(VALUE self, VALUE r_name, VALUE r_attrs)
|
|
645
353
|
document->mixed = 0;
|
646
354
|
free(attrs);
|
647
355
|
}
|
356
|
+
else
|
357
|
+
{
|
358
|
+
++document->level;
|
359
|
+
}
|
648
360
|
|
649
|
-
return
|
361
|
+
return RTEST(document->ok);
|
650
362
|
}
|
651
363
|
|
652
364
|
/*
|
653
365
|
* to be called by SAX end tag handler
|
654
366
|
* @param [String] r_name tag name, must be in the form 'NS_URI:TAG_NAME'
|
655
|
-
* @return [
|
367
|
+
* @return [Boolean]
|
656
368
|
*/
|
657
369
|
VALUE rb_document_end_tag(VALUE self, VALUE r_name)
|
658
370
|
{
|
659
371
|
document_t *document;
|
660
372
|
Data_Get_Struct(self, document_t, document);
|
661
373
|
|
662
|
-
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)
|
663
378
|
{
|
664
379
|
char *name;
|
665
380
|
|
@@ -668,15 +383,21 @@ VALUE rb_document_end_tag(VALUE self, VALUE r_name)
|
|
668
383
|
|
669
384
|
flush_text(document);
|
670
385
|
|
671
|
-
//printf("RNV END %d/%d %s\n", current, previous, name);
|
672
386
|
document->ok = rnv_end_tag(document->rnv, document->drv_st, document->rn_st,
|
673
387
|
&document->current, &document->previous, (char *)name) &&
|
674
388
|
document->ok;
|
675
389
|
|
676
390
|
document->mixed = 1;
|
677
391
|
}
|
392
|
+
else
|
393
|
+
{
|
394
|
+
if (document->level == 0)
|
395
|
+
document->current = document->previous;
|
396
|
+
else
|
397
|
+
--document->level;
|
398
|
+
}
|
678
399
|
|
679
|
-
return
|
400
|
+
return RTEST(document->ok);
|
680
401
|
}
|
681
402
|
|
682
403
|
// The initialization method for this module
|
@@ -684,21 +405,15 @@ void Init_rnv()
|
|
684
405
|
{
|
685
406
|
RNV = rb_define_module("RNV");
|
686
407
|
|
687
|
-
|
408
|
+
SchemaNotLoaded = rb_define_class_under(RNV, "SchemaNotLoaded", rb_eStandardError);
|
688
409
|
|
689
|
-
|
690
|
-
rb_define_method(Error, "to_s", rb_error_to_s, 0);
|
410
|
+
Error = rb_define_class_under(RNV, "Error", rb_cObject);
|
691
411
|
|
692
412
|
/*
|
693
413
|
* error symbol code
|
694
414
|
* @return [Symbol]
|
695
415
|
*/
|
696
416
|
rb_define_attr(Error, "code", 1, 0);
|
697
|
-
/*
|
698
|
-
* error message
|
699
|
-
* @return [String]
|
700
|
-
*/
|
701
|
-
rb_define_attr(Error, "message", 1, 0);
|
702
417
|
/*
|
703
418
|
* error line
|
704
419
|
* @return [Integer]
|
@@ -710,7 +425,17 @@ void Init_rnv()
|
|
710
425
|
*/
|
711
426
|
rb_define_attr(Error, "col", 1, 0);
|
712
427
|
|
713
|
-
|
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);
|
714
439
|
|
715
440
|
rb_define_alloc_func(Document, rb_document_alloc);
|
716
441
|
rb_define_method(Document, "initialize", rb_document_init, 0);
|
@@ -719,6 +444,8 @@ void Init_rnv()
|
|
719
444
|
rb_define_method(Document, "load_string", rb_document_load_string, 1);
|
720
445
|
rb_define_method(Document, "valid?", rb_document_valid, 0);
|
721
446
|
|
447
|
+
rb_define_method(Document, "add_datatype_library", rb_document_add_dtl, 2);
|
448
|
+
|
722
449
|
rb_define_method(Document, "start_document", rb_document_begin, 0);
|
723
450
|
rb_define_method(Document, "start_tag", rb_document_start_tag, 2);
|
724
451
|
rb_define_method(Document, "characters", rb_document_characters, 1);
|