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 +4 -4
- data/ext/rnv/extconf.rb +1 -1
- data/ext/rnv/ruby_rnv.c +163 -438
- 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 +87 -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 +61 -28
- 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 +22 -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: 899300861f1a2b315f879d451a7a5ee472302fbdac26ea775a2e56e09793d98c
|
|
4
|
+
data.tar.gz: 4f2139ddde96c34a077e124600bb7cbbb0e98ef5db5fe5c57066bdcc8fd4c089
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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");
|
|
16
|
+
Check_Type(r_msg, T_STRING);
|
|
270
17
|
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
|
@@ -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 [
|
|
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
|
|
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
|
|
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
|
|
612
|
-
* @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]
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
|
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 [
|
|
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
|
|
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
|
|
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
|
-
|
|
408
|
+
SchemaNotLoaded = rb_define_class_under(RNV, "SchemaNotLoaded", rb_eStandardError);
|
|
690
409
|
|
|
691
|
-
|
|
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
|
-
|
|
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);
|