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.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/ext/rnv/extconf.rb +15 -0
- data/ext/rnv/ruby_rnv.c +742 -0
- data/ext/rnv/src/ary.c +78 -0
- data/ext/rnv/src/ary.h +10 -0
- data/ext/rnv/src/drv.c +472 -0
- data/ext/rnv/src/drv.h +35 -0
- data/ext/rnv/src/er.c +15 -0
- data/ext/rnv/src/er.h +16 -0
- data/ext/rnv/src/erbit.h +14 -0
- data/ext/rnv/src/ht.c +90 -0
- data/ext/rnv/src/ht.h +22 -0
- data/ext/rnv/src/ll.h +43 -0
- data/ext/rnv/src/m.c +60 -0
- data/ext/rnv/src/m.h +10 -0
- data/ext/rnv/src/rn.c +569 -0
- data/ext/rnv/src/rn.h +150 -0
- data/ext/rnv/src/rnc.c +1191 -0
- data/ext/rnv/src/rnc.h +68 -0
- data/ext/rnv/src/rnd.c +436 -0
- data/ext/rnv/src/rnd.h +25 -0
- data/ext/rnv/src/rnl.c +62 -0
- data/ext/rnv/src/rnl.h +18 -0
- data/ext/rnv/src/rnv.c +158 -0
- data/ext/rnv/src/rnv.h +30 -0
- data/ext/rnv/src/rnx.c +153 -0
- data/ext/rnv/src/rnx.h +16 -0
- data/ext/rnv/src/rx.c +749 -0
- data/ext/rnv/src/rx.h +43 -0
- data/ext/rnv/src/rx_cls_ranges.c +126 -0
- data/ext/rnv/src/rx_cls_u.c +262 -0
- data/ext/rnv/src/s.c +103 -0
- data/ext/rnv/src/s.h +32 -0
- data/ext/rnv/src/sc.c +62 -0
- data/ext/rnv/src/sc.h +26 -0
- data/ext/rnv/src/type.h +121 -0
- data/ext/rnv/src/u.c +88 -0
- data/ext/rnv/src/u.h +26 -0
- data/ext/rnv/src/xcl.c +472 -0
- data/ext/rnv/src/xmlc.c +20 -0
- data/ext/rnv/src/xmlc.h +16 -0
- data/ext/rnv/src/xsd.c +789 -0
- data/ext/rnv/src/xsd.h +27 -0
- data/ext/rnv/src/xsd_tm.c +100 -0
- data/ext/rnv/src/xsd_tm.h +15 -0
- data/lib/rnv.rb +2 -0
- data/lib/rnv/ox_sax_document.rb +84 -0
- data/lib/rnv/validator.rb +104 -0
- 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
|
+
}
|