ruby_rnv 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }