ruby_rnv 0.2.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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/ext/rnv/extconf.rb +15 -0
  4. data/ext/rnv/ruby_rnv.c +742 -0
  5. data/ext/rnv/src/ary.c +78 -0
  6. data/ext/rnv/src/ary.h +10 -0
  7. data/ext/rnv/src/drv.c +472 -0
  8. data/ext/rnv/src/drv.h +35 -0
  9. data/ext/rnv/src/er.c +15 -0
  10. data/ext/rnv/src/er.h +16 -0
  11. data/ext/rnv/src/erbit.h +14 -0
  12. data/ext/rnv/src/ht.c +90 -0
  13. data/ext/rnv/src/ht.h +22 -0
  14. data/ext/rnv/src/ll.h +43 -0
  15. data/ext/rnv/src/m.c +60 -0
  16. data/ext/rnv/src/m.h +10 -0
  17. data/ext/rnv/src/rn.c +569 -0
  18. data/ext/rnv/src/rn.h +150 -0
  19. data/ext/rnv/src/rnc.c +1191 -0
  20. data/ext/rnv/src/rnc.h +68 -0
  21. data/ext/rnv/src/rnd.c +436 -0
  22. data/ext/rnv/src/rnd.h +25 -0
  23. data/ext/rnv/src/rnl.c +62 -0
  24. data/ext/rnv/src/rnl.h +18 -0
  25. data/ext/rnv/src/rnv.c +158 -0
  26. data/ext/rnv/src/rnv.h +30 -0
  27. data/ext/rnv/src/rnx.c +153 -0
  28. data/ext/rnv/src/rnx.h +16 -0
  29. data/ext/rnv/src/rx.c +749 -0
  30. data/ext/rnv/src/rx.h +43 -0
  31. data/ext/rnv/src/rx_cls_ranges.c +126 -0
  32. data/ext/rnv/src/rx_cls_u.c +262 -0
  33. data/ext/rnv/src/s.c +103 -0
  34. data/ext/rnv/src/s.h +32 -0
  35. data/ext/rnv/src/sc.c +62 -0
  36. data/ext/rnv/src/sc.h +26 -0
  37. data/ext/rnv/src/type.h +121 -0
  38. data/ext/rnv/src/u.c +88 -0
  39. data/ext/rnv/src/u.h +26 -0
  40. data/ext/rnv/src/xcl.c +472 -0
  41. data/ext/rnv/src/xmlc.c +20 -0
  42. data/ext/rnv/src/xmlc.h +16 -0
  43. data/ext/rnv/src/xsd.c +789 -0
  44. data/ext/rnv/src/xsd.h +27 -0
  45. data/ext/rnv/src/xsd_tm.c +100 -0
  46. data/ext/rnv/src/xsd_tm.h +15 -0
  47. data/lib/rnv.rb +2 -0
  48. data/lib/rnv/ox_sax_document.rb +84 -0
  49. data/lib/rnv/validator.rb +104 -0
  50. metadata +175 -0
data/ext/rnv/src/rnc.h ADDED
@@ -0,0 +1,68 @@
1
+ /* $Id: rnc.h,v 1.13 2004/01/02 20:27:23 dvd Exp $ */
2
+
3
+ #include <stdarg.h>
4
+ #include "type.h"
5
+
6
+ #ifndef RNC_H
7
+ #define RNC_H 1
8
+
9
+ #define RNC_ER_IO 0
10
+ #define RNC_ER_UTF 10
11
+ #define RNC_ER_XESC 20
12
+ #define RNC_ER_LEXP 30
13
+ #define RNC_ER_LLIT 31
14
+ #define RNC_ER_LILL 32
15
+ #define RNC_ER_SEXP 40
16
+ #define RNC_ER_SILL 41
17
+ #define RNC_ER_NOTGR 42
18
+ #define RNC_ER_EXT 50
19
+ #define RNC_ER_DUPNS 51
20
+ #define RNC_ER_DUPDT 52
21
+ #define RNC_ER_DFLTNS 53
22
+ #define RNC_ER_DFLTDT 54
23
+ #define RNC_ER_NONS 55
24
+ #define RNC_ER_NODT 56
25
+ #define RNC_ER_NCEX 57
26
+ #define RNC_ER_2HEADS 58
27
+ #define RNC_ER_COMBINE 59
28
+ #define RNC_ER_OVRIDE 60
29
+ #define RNC_ER_EXPT 61
30
+ #define RNC_ER_INCONT 62
31
+ #define RNC_ER_NOSTART 70
32
+ #define RNC_ER_UNDEF 71
33
+
34
+ struct rnc_cym {
35
+ char *s; int slen;
36
+ int line,col;
37
+ int sym;
38
+ };
39
+
40
+ struct rnc_source {
41
+ int flags;
42
+ char *fn; int fd;
43
+ char *buf; int i,n;
44
+ int complete;
45
+ int line,col,prevline/*when error reported*/;
46
+ int u,v,w; int nx;
47
+ int cur;
48
+ struct rnc_cym sym[2];
49
+
50
+ // FIXME: for error handlers
51
+ rnv_t *rnv;
52
+ };
53
+
54
+ extern void rnc_default_verror_handler(rnv_t *rnv, int erno,va_list ap);
55
+
56
+ extern void rnc_init(rnv_t *rnv, rnc_st_t *rnc_st, rn_st_t *rn_st);
57
+ extern void rnc_clear(void);
58
+
59
+ extern int rnc_open(struct rnc_source *sp,char *fn);
60
+ extern int rnc_stropen(struct rnc_source *sp,char *fn,char *s,int len);
61
+ extern int rnc_bind(struct rnc_source *sp,char *fn,int fd);
62
+ extern int rnc_close(struct rnc_source *sp);
63
+
64
+ extern int rnc_parse(rnv_t *rnv, rnc_st_t *rnc_st, rn_st_t *rn_st, struct rnc_source *sp);
65
+
66
+ extern int rnc_errors(struct rnc_source *sp);
67
+
68
+ #endif
data/ext/rnv/src/rnd.c ADDED
@@ -0,0 +1,436 @@
1
+ #include "type.h"
2
+
3
+ /* $Id: rnd.c,v 1.33 2004/02/25 00:00:32 dvd Exp $ */
4
+
5
+ #include <stdlib.h>
6
+ #include <assert.h>
7
+ #include <string.h>
8
+ #include "m.h"
9
+ #include "rn.h"
10
+ #include "rnx.h"
11
+ #include "ll.h"
12
+ #include "er.h"
13
+ #include "rnd.h"
14
+ #include "erbit.h"
15
+
16
+ #define LEN_F RND_LEN_F
17
+
18
+ #define err(msg) (*rnv->verror_handler)(rnv,erno|ERBIT_RND,"error: "msg"\n",ap)
19
+ void rnd_default_verror_handler(rnv_t *rnv, int erno,va_list ap) {
20
+ switch(erno) {
21
+ case RND_ER_LOOPST: err("loop in start pattern"); break;
22
+ case RND_ER_LOOPEL: err("loop in pattern for element '%s'"); break;
23
+ case RND_ER_CTYPE: err("content of element '%s' does not have a content-type"); break;
24
+ case RND_ER_BADSTART: err("bad path in start pattern"); break;
25
+ case RND_ER_BADMORE: err("bad path before '*' or '+' in element '%s'"); break;
26
+ case RND_ER_BADEXPT: err("bad path after '-' in element '%s'"); break;
27
+ case RND_ER_BADLIST: err("bad path after 'list' in element '%s'"); break;
28
+ case RND_ER_BADATTR: err("bad path in attribute '%s' of element '%s'"); break;
29
+ default: assert(0);
30
+ }
31
+ }
32
+
33
+ void rnd_init(rnv_t *rnv, rnd_st_t *rnd_st, rn_st_t *rn_st) {
34
+ memset(rnd_st, 0, sizeof(rnd_st_t));
35
+ rnv->rnd_verror_handler=&rnd_default_verror_handler;
36
+ rn_init(rnv, rn_st);
37
+ }
38
+
39
+ void rnd_clear(void) {}
40
+
41
+ static void error_handler(rnv_t *rnv, rnd_st_t *rnd_st, int er_no,...) {
42
+ va_list ap; va_start(ap,er_no);
43
+ rnv->rnd_verror_handler(rnv, er_no,ap);
44
+ va_end(ap);
45
+ ++rnd_st->errors;
46
+ }
47
+
48
+ static int de(rnv_t *rnv, int p) {
49
+ int p0=p,p1;
50
+ RN_P_CHK(p,RN_P_REF);
51
+ for(;;) {
52
+ rn_Ref(p,p1);
53
+ if(!RN_P_IS(p1,RN_P_REF)||p1==p0) break;
54
+ p=p1;
55
+ }
56
+ return p1;
57
+ }
58
+
59
+ static void flatten(rnv_t *rnv, rnd_st_t *rnd_st, int p) { if(!rn_marked(p)) {rnd_st->flat[rnd_st->n_f++]=p; rn_mark(p);}}
60
+
61
+ static void deref(rnv_t *rnv, rnd_st_t *rnd_st, rn_st_t *rn_st, int start) {
62
+ int p,p1,p2,nc,i,changed;
63
+
64
+ rnd_st->flat=(int*)m_alloc(rnd_st->len_f=LEN_F,sizeof(int)); rnd_st->n_f=0;
65
+ if(RN_P_IS(start,RN_P_REF)) start=de(rnv, start);
66
+ flatten(rnv, rnd_st, start);
67
+
68
+ i=0;
69
+ do {
70
+ p=rnd_st->flat[i++];
71
+ switch(RN_P_TYP(p)) {
72
+ case RN_P_NOT_ALLOWED: case RN_P_EMPTY: case RN_P_TEXT: case RN_P_DATA: case RN_P_VALUE:
73
+ break;
74
+
75
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); goto BINARY;
76
+ case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); goto BINARY;
77
+ case RN_P_GROUP: rn_Group(p,p1,p2); goto BINARY;
78
+ case RN_P_DATA_EXCEPT: rn_DataExcept(p,p1,p2); goto BINARY;
79
+ BINARY:
80
+ changed=0;
81
+ if(RN_P_IS(p1,RN_P_REF)) {p1=de(rnv, p1); changed=1;}
82
+ if(RN_P_IS(p2,RN_P_REF)) {p2=de(rnv, p2); changed=1;}
83
+ if(changed) {rn_del_p(rn_st, p); rnv->rn_pattern[p+1]=p1; rnv->rn_pattern[p+2]=p2; rn_add_p(rn_st, p);}
84
+ if(rnd_st->n_f+2>rnd_st->len_f) rnd_st->flat=(int*)m_stretch(rnd_st->flat,rnd_st->len_f=2*(rnd_st->n_f+2),rnd_st->n_f,sizeof(int));
85
+ flatten(rnv, rnd_st, p1); flatten(rnv, rnd_st, p2);
86
+ break;
87
+
88
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); goto UNARY;
89
+ case RN_P_LIST: rn_List(p,p1); goto UNARY;
90
+ case RN_P_ATTRIBUTE: rn_Attribute(p,nc,p1); goto UNARY;
91
+ case RN_P_ELEMENT: rn_Element(p,nc,p1); goto UNARY;
92
+ UNARY:
93
+ changed=0;
94
+ if(RN_P_IS(p1,RN_P_REF)) {p1=de(rnv, p1); changed=1;}
95
+ if(changed) {rn_del_p(rn_st, p); rnv->rn_pattern[p+1]=p1; rn_add_p(rn_st, p);}
96
+ if(rnd_st->n_f+1>rnd_st->len_f) rnd_st->flat=(int*)m_stretch(rnd_st->flat,rnd_st->len_f=2*(rnd_st->n_f+1),rnd_st->n_f,sizeof(int));
97
+ flatten(rnv, rnd_st, p1);
98
+ break;
99
+
100
+ case RN_P_REF: /* because of a loop, but will be handled in rnd_loops */
101
+ break;
102
+
103
+ default:
104
+ assert(0);
105
+ }
106
+ } while(i!=rnd_st->n_f);
107
+ for(i=0;i!=rnd_st->n_f;++i) rn_unmark(rnd_st->flat[i]);
108
+ }
109
+
110
+ static int loop(rnv_t *rnv, int p) {
111
+ int nc,p1,p2,ret=1;
112
+ if(rn_marked(p)) return 1;
113
+ rn_mark(p);
114
+ switch(RN_P_TYP(p)) {
115
+ case RN_P_NOT_ALLOWED: case RN_P_EMPTY: case RN_P_TEXT: case RN_P_DATA: case RN_P_VALUE:
116
+ case RN_P_ELEMENT:
117
+ ret=0; break;
118
+
119
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); goto BINARY;
120
+ case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); goto BINARY;
121
+ case RN_P_GROUP: rn_Group(p,p1,p2); goto BINARY;
122
+ case RN_P_DATA_EXCEPT: rn_DataExcept(p,p1,p2); goto BINARY;
123
+ BINARY:
124
+ ret=loop(rnv, p1)||loop(rnv, p2); break;
125
+
126
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); goto UNARY;
127
+ case RN_P_LIST: rn_List(p,p1); goto UNARY;
128
+ case RN_P_ATTRIBUTE: rn_Attribute(p,nc,p1); goto UNARY;
129
+ UNARY:
130
+ ret=loop(rnv, p1); break;
131
+
132
+ case RN_P_REF: ret=1; break;
133
+
134
+ default: assert(0);
135
+ }
136
+ rn_unmark(p);
137
+ return ret;
138
+ }
139
+
140
+ static void loops(rnv_t *rnv, rnd_st_t *rnd_st) {
141
+ int i=0,p=rnd_st->flat[i],nc=-1,p1;
142
+ for(;;) {
143
+ if(loop(rnv, p)) {
144
+ if(i==0) error_handler(rnv, rnd_st, RND_ER_LOOPST); else {
145
+ char *s=rnx_nc2str(rnv, nc);
146
+ error_handler(rnv, rnd_st,RND_ER_LOOPEL, s);
147
+ m_free(s);
148
+ }
149
+ }
150
+ for(;;) {++i;
151
+ if(i==rnd_st->n_f) return;
152
+ p=rnd_st->flat[i];
153
+ if(RN_P_IS(p,RN_P_ELEMENT)) {
154
+ rn_Element(p,nc,p1); p=p1;
155
+ break;
156
+ }
157
+ }
158
+ }
159
+ }
160
+
161
+ static void ctype(rnv_t *rnv, int p) {
162
+ int p1,p2,nc;
163
+ if(!rn_contentType(rnv, p)) {
164
+ switch(RN_P_TYP(p)) {
165
+ case RN_P_NOT_ALLOWED: rn_setContentType(rnv, p,RN_P_FLG_CTE,0); break;
166
+ case RN_P_EMPTY: rn_setContentType(rnv, p,RN_P_FLG_CTE,0); break;
167
+ case RN_P_TEXT: rn_setContentType(rnv, p,RN_P_FLG_CTC,0); break;
168
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); ctype(rnv, p1); ctype(rnv, p2);
169
+ rn_setContentType(rnv, p,rn_contentType(rnv, p1),rn_contentType(rnv, p2)); break;
170
+ case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); ctype(rnv, p1); ctype(rnv, p2);
171
+ if(rn_groupable(rnv, p1,p2)) rn_setContentType(rnv, p,rn_contentType(rnv, p1),rn_contentType(rnv, p2)); break;
172
+ case RN_P_GROUP: rn_Group(p,p1,p2); ctype(rnv, p1); ctype(rnv, p2);
173
+ if(rn_groupable(rnv, p1,p2)) rn_setContentType(rnv, p,rn_contentType(rnv, p1),rn_contentType(rnv, p2)); break;
174
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); ctype(rnv, p1);
175
+ if(rn_groupable(rnv, p1,p1)) rn_setContentType(rnv, p,rn_contentType(rnv, p1),0); break;
176
+ case RN_P_LIST: rn_setContentType(rnv, p,RN_P_FLG_CTS,0); break;
177
+ case RN_P_DATA: rn_setContentType(rnv, p,RN_P_FLG_CTS,0); break;
178
+ case RN_P_DATA_EXCEPT: rn_DataExcept(p,p1,p2); ctype(rnv, p1); ctype(rnv, p2);
179
+ if(rn_contentType(rnv, p2)) rn_setContentType(rnv, p,RN_P_FLG_CTS,0); break;
180
+ case RN_P_VALUE: rn_setContentType(rnv, p,RN_P_FLG_CTS,0); break;
181
+ case RN_P_ATTRIBUTE: rn_Attribute(p,nc,p1); ctype(rnv, p1);
182
+ if(rn_contentType(rnv, p1)) rn_setContentType(rnv, p,RN_P_FLG_CTE,0); break;
183
+ case RN_P_ELEMENT: rn_setContentType(rnv, p,RN_P_FLG_CTC,0); break;
184
+ default: assert(0);
185
+ }
186
+ }
187
+ }
188
+
189
+ static void ctypes(rnv_t *rnv, rnd_st_t *rnd_st) {
190
+ int i,p,p1,nc;
191
+ for(i=0;i!=rnd_st->n_f;++i) {
192
+ p=rnd_st->flat[i];
193
+ if(RN_P_IS(p,RN_P_ELEMENT)) {
194
+ rn_Element(p,nc,p1);
195
+ ctype(rnv, p1);
196
+ if(!rn_contentType(rnv, p1)) {
197
+ char *s=rnx_nc2str(rnv, nc);
198
+ error_handler(rnv,rnd_st,RND_ER_CTYPE, s);
199
+ m_free(s);
200
+ }
201
+ }
202
+ }
203
+ }
204
+
205
+ static int bad_start(rnv_t *rnv, int p) {
206
+ int p1,p2;
207
+ switch(RN_P_TYP(p)) {
208
+ case RN_P_EMPTY: case RN_P_TEXT:
209
+ case RN_P_INTERLEAVE: case RN_P_GROUP: case RN_P_ONE_OR_MORE:
210
+ case RN_P_LIST: case RN_P_DATA: case RN_P_DATA_EXCEPT: case RN_P_VALUE:
211
+ case RN_P_ATTRIBUTE:
212
+ return 1;
213
+ case RN_P_NOT_ALLOWED:
214
+ case RN_P_ELEMENT:
215
+ return 0;
216
+ case RN_P_CHOICE: rn_Choice(p,p1,p2);
217
+ return bad_start(rnv, p1)||bad_start(rnv, p2);
218
+ default: assert(0);
219
+ }
220
+ return 1;
221
+ }
222
+
223
+ static int bad_data_except(rnv_t *rnv, int p) {
224
+ int p1,p2;
225
+ switch(RN_P_TYP(p)) {
226
+ case RN_P_NOT_ALLOWED:
227
+ case RN_P_VALUE: case RN_P_DATA:
228
+ return 0;
229
+
230
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); goto BINARY;
231
+ case RN_P_DATA_EXCEPT: rn_Choice(p,p1,p2); goto BINARY;
232
+ BINARY: return bad_data_except(rnv, p1)||bad_data_except(rnv, p2);
233
+
234
+ case RN_P_EMPTY: case RN_P_TEXT:
235
+ case RN_P_INTERLEAVE: case RN_P_GROUP: case RN_P_ONE_OR_MORE:
236
+ case RN_P_LIST:
237
+ case RN_P_ATTRIBUTE: case RN_P_ELEMENT:
238
+ return 1;
239
+ default: assert(0);
240
+ }
241
+ return 1;
242
+ }
243
+
244
+ static int bad_one_or_more(rnv_t *rnv, int p,int in_group) {
245
+ int nc,p1,p2;
246
+ switch(RN_P_TYP(p)) {
247
+ case RN_P_NOT_ALLOWED: case RN_P_EMPTY: case RN_P_TEXT:
248
+ case RN_P_DATA: case RN_P_VALUE:
249
+ case RN_P_ELEMENT:
250
+ return 0;
251
+
252
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); goto BINARY;
253
+ case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); in_group=1; goto BINARY;
254
+ case RN_P_GROUP: rn_Group(p,p1,p2); in_group=1; goto BINARY;
255
+ case RN_P_DATA_EXCEPT: rn_DataExcept(p,p1,p2); goto BINARY;
256
+ BINARY: return bad_one_or_more(rnv, p1,in_group)||bad_one_or_more(rnv, p2,in_group);
257
+
258
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); goto UNARY;
259
+ case RN_P_LIST: rn_List(p,p1); goto UNARY;
260
+ case RN_P_ATTRIBUTE: if(in_group) return 1;
261
+ rn_Attribute(p,nc,p1); goto UNARY;
262
+ UNARY: return bad_one_or_more(rnv, p1,in_group);
263
+ default: assert(0);
264
+ }
265
+ return 1;
266
+ }
267
+
268
+ static int bad_list(rnv_t *rnv, int p) {
269
+ int p1,p2;
270
+ switch(RN_P_TYP(p)) {
271
+ case RN_P_NOT_ALLOWED: case RN_P_EMPTY:
272
+ case RN_P_DATA: case RN_P_VALUE:
273
+ return 0;
274
+
275
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); goto BINARY;
276
+ case RN_P_GROUP: rn_Group(p,p1,p2); goto BINARY;
277
+ case RN_P_DATA_EXCEPT: rn_DataExcept(p,p1,p2); goto BINARY;
278
+ BINARY: return bad_list(rnv, p1)||bad_list(rnv, p2);
279
+
280
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); goto UNARY;
281
+ case RN_P_LIST: rn_List(p,p1); goto UNARY;
282
+ UNARY: return bad_list(rnv, p1);
283
+
284
+ case RN_P_TEXT:
285
+ case RN_P_INTERLEAVE:
286
+ case RN_P_ATTRIBUTE:
287
+ case RN_P_ELEMENT:
288
+ return 1;
289
+ default: assert(0);
290
+ }
291
+ return 1;
292
+ }
293
+
294
+ static int bad_attribute(rnv_t *rnv, int p) {
295
+ int p1,p2;
296
+ switch(RN_P_TYP(p)) {
297
+ case RN_P_NOT_ALLOWED: case RN_P_EMPTY: case RN_P_TEXT:
298
+ case RN_P_DATA: case RN_P_VALUE:
299
+ return 0;
300
+
301
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); goto BINARY;
302
+ case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); goto BINARY;
303
+ case RN_P_GROUP: rn_Group(p,p1,p2); goto BINARY;
304
+ case RN_P_DATA_EXCEPT: rn_DataExcept(p,p1,p2); goto BINARY;
305
+ BINARY: return bad_attribute(rnv, p1)||bad_attribute(rnv, p2);
306
+
307
+
308
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); goto UNARY;
309
+ case RN_P_LIST: rn_List(p,p1); goto UNARY;
310
+ UNARY: return bad_attribute(rnv, p1);
311
+
312
+ case RN_P_ATTRIBUTE: case RN_P_ELEMENT:
313
+ return 1;
314
+ default: assert(0);
315
+ }
316
+ return 1;
317
+ }
318
+
319
+ static void path(rnv_t *rnv, rnd_st_t *rnd_st, int p,int nc) {
320
+ int p1,p2,nc1;
321
+ switch(RN_P_TYP(p)) {
322
+ case RN_P_NOT_ALLOWED: case RN_P_EMPTY: case RN_P_TEXT:
323
+ case RN_P_DATA: case RN_P_VALUE:
324
+ case RN_P_ELEMENT:
325
+ break;
326
+
327
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); goto BINARY;
328
+ case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); goto BINARY;
329
+ case RN_P_GROUP: rn_Group(p,p1,p2); goto BINARY;
330
+ case RN_P_DATA_EXCEPT: rn_DataExcept(p,p1,p2);
331
+ if(bad_data_except(rnv, p2)) {char *s=rnx_nc2str(rnv, nc); error_handler(rnv,rnd_st,RND_ER_BADEXPT, s); m_free(s);}
332
+ goto BINARY;
333
+ BINARY: path(rnv, rnd_st, p1,nc); path(rnv, rnd_st, p2,nc); break;
334
+
335
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1);
336
+ if(bad_one_or_more(rnv, p1,0)) {char *s=rnx_nc2str(rnv, nc); error_handler(rnv,rnd_st,RND_ER_BADMORE, s); m_free(s);}
337
+ goto UNARY;
338
+ case RN_P_LIST: rn_List(p,p1);
339
+ if(bad_list(rnv, p1)) {char *s=rnx_nc2str(rnv, nc); error_handler(rnv,rnd_st,RND_ER_BADLIST, s); m_free(s);}
340
+ goto UNARY;
341
+ case RN_P_ATTRIBUTE: rn_Attribute(p,nc1,p1);
342
+ if(bad_attribute(rnv, p1)) {char *s=rnx_nc2str(rnv, nc),*s1=rnx_nc2str(rnv, nc1); error_handler(rnv,rnd_st,RND_ER_BADATTR, s1,s); m_free(s1); m_free(s);}
343
+ goto UNARY;
344
+ UNARY: path(rnv, rnd_st, p1,nc); break;
345
+
346
+ default: assert(0);
347
+ }
348
+ }
349
+
350
+ static void paths(rnv_t *rnv, rnd_st_t *rnd_st) {
351
+ int i,p,p1,nc;
352
+ if(bad_start(rnv, rnd_st->flat[0])) error_handler(rnv,rnd_st, RND_ER_BADSTART);
353
+ for(i=0;i!=rnd_st->n_f;++i) {
354
+ p=rnd_st->flat[i];
355
+ if(RN_P_IS(p,RN_P_ELEMENT)) {
356
+ rn_Element(p,nc,p1);
357
+ path(rnv, rnd_st, p1,nc);
358
+ }
359
+ }
360
+ }
361
+
362
+ static void restrictions(rnv_t *rnv, rnd_st_t *rnd_st) {
363
+ loops(rnv, rnd_st); if(rnd_st->errors) return; /* loops can cause endless loops in subsequent calls */
364
+ ctypes(rnv, rnd_st);
365
+ paths(rnv, rnd_st);
366
+ }
367
+
368
+ static void nullables(rnv_t *rnv, rnd_st_t *rnd_st) {
369
+ int i,p,p1,p2,changed;
370
+ do {
371
+ changed=0;
372
+ for(i=0;i!=rnd_st->n_f;++i) {
373
+ p=rnd_st->flat[i];
374
+ if(!rn_nullable(p)) {
375
+ switch(RN_P_TYP(p)) {
376
+ case RN_P_NOT_ALLOWED:
377
+ case RN_P_DATA: case RN_P_DATA_EXCEPT: case RN_P_VALUE: case RN_P_LIST:
378
+ case RN_P_ATTRIBUTE: case RN_P_ELEMENT:
379
+ break;
380
+
381
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); rn_setNullable(p,rn_nullable(p1)||rn_nullable(p2)); break;
382
+ case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); rn_setNullable(p,rn_nullable(p1)&&rn_nullable(p2)); break;
383
+ case RN_P_GROUP: rn_Group(p,p1,p2); rn_setNullable(p,rn_nullable(p1)&&rn_nullable(p2)); break;
384
+
385
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); rn_setNullable(p,rn_nullable(p1)); break;
386
+
387
+ default: assert(0);
388
+ }
389
+ changed=changed||rn_nullable(p);
390
+ }
391
+ }
392
+ } while(changed);
393
+ }
394
+
395
+ static void cdatas(rnv_t *rnv, rnd_st_t *rnd_st) {
396
+ int i,p,p1,p2,changed;
397
+ do {
398
+ changed=0;
399
+ for(i=0;i!=rnd_st->n_f;++i) {
400
+ p=rnd_st->flat[i];
401
+ if(!rn_cdata(p)) {
402
+ switch(RN_P_TYP(p)) {
403
+ case RN_P_NOT_ALLOWED: case RN_P_EMPTY:
404
+ case RN_P_ATTRIBUTE: case RN_P_ELEMENT:
405
+ break;
406
+
407
+ case RN_P_CHOICE: rn_Choice(p,p1,p2); rn_setCdata(p,rn_cdata(p1)||rn_cdata(p2)); break;
408
+ case RN_P_INTERLEAVE: rn_Interleave(p,p1,p2); rn_setCdata(p,rn_cdata(p1)||rn_cdata(p2)); break;
409
+ case RN_P_GROUP: rn_Group(p,p1,p2); rn_setCdata(p,rn_cdata(p1)||rn_cdata(p2)); break;
410
+
411
+ case RN_P_ONE_OR_MORE: rn_OneOrMore(p,p1); rn_setCdata(p,rn_cdata(p1)); break;
412
+
413
+ default: assert(0);
414
+ }
415
+ changed=changed||rn_cdata(p);
416
+ }
417
+ }
418
+ } while(changed);
419
+ }
420
+
421
+ static void traits(rnv_t *rnv, rnd_st_t *rnd_st) {
422
+ nullables(rnv, rnd_st);
423
+ cdatas(rnv, rnd_st);
424
+ }
425
+
426
+ static int release(rnd_st_t *rnd_st) {
427
+ int start=rnd_st->flat[0];
428
+ m_free(rnd_st->flat); rnd_st->flat=NULL;
429
+ return start;
430
+ }
431
+
432
+ int rnd_fixup(rnv_t *rnv, rnd_st_t *rnd_st, rn_st_t *rn_st, int start) {
433
+ rnd_st->errors=0; deref(rnv, rnd_st, rn_st, start);
434
+ if(!rnd_st->errors) {restrictions(rnv, rnd_st); if(!rnd_st->errors) traits(rnv, rnd_st);}
435
+ start=release(rnd_st); return rnd_st->errors?0:start;
436
+ }