ruby_rnv 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/s.h
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
/* $Id: s.h,v 1.6 2005/01/05 09:46:25 dvd Exp $ */
|
2
|
+
|
3
|
+
#ifndef S_H
|
4
|
+
#define S_H 1
|
5
|
+
|
6
|
+
/* compares two strings, s1 is null terminated, s2 is n characters long */
|
7
|
+
extern int s_cmpn(char *s1,char *s2,int n2);
|
8
|
+
|
9
|
+
/* compares two tokens, s1 is null terminated, s2 is n characters long */
|
10
|
+
extern int s_tokcmpn(char *s1,char *s2,int n2);
|
11
|
+
|
12
|
+
/* hash value for a zero-terminated string */
|
13
|
+
extern int s_hval(char *s);
|
14
|
+
|
15
|
+
/* strdup is a non-standard function */
|
16
|
+
extern char *s_clone(char *s);
|
17
|
+
|
18
|
+
/* compute the absolute path from a relative path and a base path;
|
19
|
+
the caller must ensure that there is enough space in r:
|
20
|
+
size(r) > strlen(r)+strlen(b)
|
21
|
+
returns a pointer to the string containing the relative path
|
22
|
+
*/
|
23
|
+
extern char *s_abspath(char *r,char *b);
|
24
|
+
|
25
|
+
/* find a string in a sorted array, return the index,
|
26
|
+
or size on failure */
|
27
|
+
extern int s_tab(char *s,char *tab[],int size);
|
28
|
+
extern int s_ntab(char *s,int len,char *tab[],int size);
|
29
|
+
|
30
|
+
extern void s_test(void);
|
31
|
+
|
32
|
+
#endif
|
data/ext/rnv/src/sc.c
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
/* $Id: sc.c,v 1.16 2004/03/13 13:28:02 dvd Exp $ */
|
2
|
+
|
3
|
+
#include <assert.h> /*assert*/
|
4
|
+
#include "m.h"
|
5
|
+
#include "ll.h"
|
6
|
+
#include "sc.h"
|
7
|
+
|
8
|
+
#define BASE -1
|
9
|
+
#define LOCK -2
|
10
|
+
|
11
|
+
#define LEN SC_LEN
|
12
|
+
|
13
|
+
static void windup(struct sc_stack *stp) {
|
14
|
+
stp->top=0;
|
15
|
+
sc_open(stp);
|
16
|
+
}
|
17
|
+
|
18
|
+
void sc_init(struct sc_stack *stp) {
|
19
|
+
stp->tab=(int(*)[SC_RECSIZE])m_alloc(stp->len=LEN,sizeof(int[SC_RECSIZE]));
|
20
|
+
windup(stp);
|
21
|
+
}
|
22
|
+
|
23
|
+
void sc_clear(struct sc_stack *stp) {
|
24
|
+
windup(stp);
|
25
|
+
}
|
26
|
+
|
27
|
+
void sc_open(struct sc_stack *stp) {
|
28
|
+
stp->tab[stp->base=stp->top++][1]=BASE;
|
29
|
+
if(stp->top==stp->len) stp->tab=(int(*)[SC_RECSIZE])m_stretch(
|
30
|
+
stp->tab,stp->len*=stp->top*2,stp->top,sizeof(int[SC_RECSIZE]));
|
31
|
+
}
|
32
|
+
|
33
|
+
int sc_void(struct sc_stack *stp) {
|
34
|
+
return stp->base==0;
|
35
|
+
}
|
36
|
+
|
37
|
+
void sc_lock(struct sc_stack *stp) {
|
38
|
+
stp->tab[stp->base][1]=LOCK;
|
39
|
+
}
|
40
|
+
|
41
|
+
int sc_locked(struct sc_stack *stp) {
|
42
|
+
return stp->tab[stp->base][1]==LOCK;
|
43
|
+
}
|
44
|
+
|
45
|
+
void sc_close(struct sc_stack *stp) {
|
46
|
+
stp->top=stp->base; while(stp->tab[--stp->base][1]>BASE);
|
47
|
+
}
|
48
|
+
|
49
|
+
int sc_find(struct sc_stack *stp,int key) {
|
50
|
+
int i=stp->top; stp->tab[stp->base][0]=key;
|
51
|
+
while(stp->tab[--i][0]!=key);
|
52
|
+
return i!=stp->base?i:0;
|
53
|
+
}
|
54
|
+
|
55
|
+
int sc_add(struct sc_stack *stp,int key,int val,int aux) {
|
56
|
+
int i=stp->top;
|
57
|
+
assert(!sc_locked(stp));
|
58
|
+
stp->tab[i][0]=key; stp->tab[i][1]=val; stp->tab[i][2]=aux;
|
59
|
+
if(++stp->top==stp->len) stp->tab=(int(*)[SC_RECSIZE])m_stretch(
|
60
|
+
stp->tab,stp->len=stp->top*2,stp->top,sizeof(int[SC_RECSIZE]));
|
61
|
+
return i;
|
62
|
+
}
|
data/ext/rnv/src/sc.h
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
/* $Id: sc.h,v 1.7 2004/01/15 23:47:45 dvd Exp $ */
|
2
|
+
|
3
|
+
#ifndef SC_H
|
4
|
+
#define SC_H 1
|
5
|
+
|
6
|
+
#define SC_RECSIZE 3 /* 0 - key, 1 - value, 2 - auxiliary */
|
7
|
+
|
8
|
+
struct sc_stack {
|
9
|
+
int (*tab)[SC_RECSIZE];
|
10
|
+
int len,base,top;
|
11
|
+
};
|
12
|
+
|
13
|
+
extern void sc_init(struct sc_stack *stp);
|
14
|
+
extern void sc_clear(struct sc_stack *stp);
|
15
|
+
|
16
|
+
extern void sc_open(struct sc_stack *stp);
|
17
|
+
extern void sc_lock(struct sc_stack *stp);
|
18
|
+
extern void sc_close(struct sc_stack *stp);
|
19
|
+
|
20
|
+
extern int sc_void(struct sc_stack *sp);
|
21
|
+
extern int sc_locked(struct sc_stack *stp);
|
22
|
+
|
23
|
+
extern int sc_find(struct sc_stack *stp,int key); /* returns 0 if not found, index in tab otherwise */
|
24
|
+
extern int sc_add(struct sc_stack *stp,int key,int val,int aux); /* returns index for the new record */
|
25
|
+
|
26
|
+
#endif
|
data/ext/rnv/src/type.h
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
#ifndef TYPE_H
|
2
|
+
#define TYPE_H
|
3
|
+
|
4
|
+
#include <stdarg.h>
|
5
|
+
#include "ht.h"
|
6
|
+
#include "sc.h"
|
7
|
+
|
8
|
+
typedef struct rn_st
|
9
|
+
{
|
10
|
+
struct hashtable ht_p;
|
11
|
+
struct hashtable ht_nc;
|
12
|
+
struct hashtable ht_s;
|
13
|
+
int i_p;
|
14
|
+
int i_nc;
|
15
|
+
int i_s;
|
16
|
+
int BASE_P;
|
17
|
+
int base_p;
|
18
|
+
int i_ref;
|
19
|
+
int len_p;
|
20
|
+
int len_nc;
|
21
|
+
int len_s;
|
22
|
+
int adding_ps;
|
23
|
+
} rn_st_t;
|
24
|
+
|
25
|
+
typedef struct rnd_st
|
26
|
+
{
|
27
|
+
int len_f;
|
28
|
+
int n_f;
|
29
|
+
int *flat;
|
30
|
+
int errors;
|
31
|
+
} rnd_st_t;
|
32
|
+
|
33
|
+
typedef struct rnv rnv_t;
|
34
|
+
typedef struct rx_st
|
35
|
+
{
|
36
|
+
char *regex;
|
37
|
+
int *pattern;
|
38
|
+
struct hashtable ht_r;
|
39
|
+
struct hashtable ht_p;
|
40
|
+
struct hashtable ht_2;
|
41
|
+
int i_p;
|
42
|
+
int len_p;
|
43
|
+
int i_r;
|
44
|
+
int len_r;
|
45
|
+
int i_2;
|
46
|
+
int len_2;
|
47
|
+
int empty;
|
48
|
+
int notAllowed;
|
49
|
+
int any;
|
50
|
+
int i_m;
|
51
|
+
int len_m;
|
52
|
+
struct hashtable ht_m;
|
53
|
+
int r0;
|
54
|
+
int ri;
|
55
|
+
int sym;
|
56
|
+
int val;
|
57
|
+
int errors;
|
58
|
+
int (*memo)[3];
|
59
|
+
int (*r2p)[2];
|
60
|
+
|
61
|
+
// FIXME: for error handlers
|
62
|
+
rnv_t *rnv;
|
63
|
+
} rx_st_t;
|
64
|
+
|
65
|
+
typedef struct rnx_st
|
66
|
+
{
|
67
|
+
int len_exp;
|
68
|
+
} rnx_st_t;
|
69
|
+
|
70
|
+
typedef struct rnc_st
|
71
|
+
{
|
72
|
+
int len_p;
|
73
|
+
char *path;
|
74
|
+
struct sc_stack nss;
|
75
|
+
struct sc_stack dts;
|
76
|
+
struct sc_stack defs;
|
77
|
+
struct sc_stack refs;
|
78
|
+
struct sc_stack prefs;
|
79
|
+
} rnc_st_t;
|
80
|
+
|
81
|
+
typedef struct drv_st
|
82
|
+
{
|
83
|
+
struct dtl *dtl;
|
84
|
+
int len_dtl;
|
85
|
+
int n_dtl;
|
86
|
+
int i_m;
|
87
|
+
int len_m;
|
88
|
+
struct hashtable ht_m;
|
89
|
+
int (*memo)[5];
|
90
|
+
} drv_st_t;
|
91
|
+
|
92
|
+
typedef struct rnv
|
93
|
+
{
|
94
|
+
int *rn_pattern;
|
95
|
+
int *rn_nameclass;
|
96
|
+
char *rn_string;
|
97
|
+
int rn_empty;
|
98
|
+
int rn_text;
|
99
|
+
int rn_notAllowed;
|
100
|
+
int rn_dt_string;
|
101
|
+
int rn_dt_token;
|
102
|
+
int rn_xsd_uri;
|
103
|
+
int rx_compact;
|
104
|
+
int rnx_n_exp;
|
105
|
+
int *rnx_exp;
|
106
|
+
int drv_compact;
|
107
|
+
|
108
|
+
int (*verror_handler)(rnv_t *rnv, int erno, char *format,va_list ap);
|
109
|
+
void (*drv_verror_handler)(rnv_t *rnv, int erno, va_list ap);
|
110
|
+
void (*rnc_verror_handler)(rnv_t *rnv, int erno, va_list ap);
|
111
|
+
void (*rnd_verror_handler)(rnv_t *rnv, int erno, va_list ap);
|
112
|
+
void (*rnl_verror_handler)(rnv_t *rnv, int erno, va_list ap);
|
113
|
+
void (*rnv_verror_handler)(rnv_t *rnv, int erno, va_list ap);
|
114
|
+
void (*rx_verror_handler)(rnv_t *rnv, int erno, va_list ap);
|
115
|
+
void (*xsd_verror_handler)(rnv_t *rnv, int erno, va_list ap);
|
116
|
+
|
117
|
+
void *user_data;
|
118
|
+
|
119
|
+
} rnv_t;
|
120
|
+
|
121
|
+
#endif // TYPE_H
|
data/ext/rnv/src/u.c
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
/* $Id: u.c,v 1.24 2004/01/25 09:44:04 dvd Exp $ */
|
2
|
+
|
3
|
+
#include "u.h"
|
4
|
+
|
5
|
+
#define ux(u,c) (((u)<<6)|(c&0x3F))
|
6
|
+
#define u1(t) t[0]
|
7
|
+
#define u2(t) ux(t[0]&0x1F,t[1])
|
8
|
+
#define u3(t) ux(ux(t[0]&0xF,t[1]),t[2])
|
9
|
+
#define u4(t) ux(ux(ux(t[0]&0x7,t[1]),t[2]),t[3])
|
10
|
+
#define u5(t) ux(ux(ux(ux(t[0]&0x3,t[1]),t[2]),t[3]),t[4])
|
11
|
+
#define u6(t) ux(ux(ux(ux(ux(t[0]&0x1,t[1]),t[2]),t[3]),t[4]),t[5])
|
12
|
+
|
13
|
+
#define vx(c,u) c=0x80|((u)&0x3F)
|
14
|
+
#define v1(t,u) t[0]=u
|
15
|
+
#define v2(t,u) t[0]=0xC0|(u>>6);vx(t[1],u)
|
16
|
+
#define v3(t,u) t[0]=0xE0|(u>>12);vx(t[1],u>>6);vx(t[2],u)
|
17
|
+
#define v4(t,u) t[0]=0xF0|(u>>18);vx(t[1],u>>12);vx(t[2],u>>6);vx(t[3],u)
|
18
|
+
#define v5(t,u) t[0]=0xF8|(u>>24);vx(t[1],u>>18);vx(t[2],u>>12);vx(t[3],u>>6);vx(t[4],u)
|
19
|
+
#define v6(t,u) t[0]=0xFC|(u>>30);vx(t[1],u>>24);vx(t[2],u>>18);vx(t[3],u>>12);vx(t[4],u>>6);vx(t[5],u)
|
20
|
+
|
21
|
+
#define B1 0xFFFFFF80
|
22
|
+
#define B2 0xFFFFF800
|
23
|
+
#define B3 0xFFFF0000
|
24
|
+
#define B4 0xFFE00000
|
25
|
+
#define B5 0xFC000000
|
26
|
+
#define B6 0x80000000
|
27
|
+
|
28
|
+
#define BOM "\xEF\xBB\xBF"
|
29
|
+
#define BOMLEN 3
|
30
|
+
|
31
|
+
int u_bom(char *s,int n) {
|
32
|
+
char *bom=(char*)(BOM+BOMLEN);
|
33
|
+
if(n>=BOMLEN) {
|
34
|
+
n=BOMLEN; s+=n;
|
35
|
+
while(n--!=0) if(*(--s)!=*(--bom)) return 0;
|
36
|
+
return BOMLEN;
|
37
|
+
}
|
38
|
+
return 0;
|
39
|
+
}
|
40
|
+
|
41
|
+
int u_get(int *up,char *s) {
|
42
|
+
unsigned char *t=(unsigned char*)s;
|
43
|
+
if(*t<0x80) {*up=u1(t); return 1;}
|
44
|
+
if(*t<0xC0) return 0;
|
45
|
+
if(*t<0xE0) {*up=u2(t); return (*up&B1)?2:0;}
|
46
|
+
if(*t<0xF0) {*up=u3(t); return (*up&B2)?3:0;}
|
47
|
+
if(*t<0xF8) {*up=u4(t); return (*up&B3)?4:0;}
|
48
|
+
if(*t<0xFC) {*up=u5(t); return (*up&B4)?5:0;}
|
49
|
+
if(*t<0xFE) {*up=u6(t); return (*up&B5)?6:0;}
|
50
|
+
return 0;
|
51
|
+
}
|
52
|
+
|
53
|
+
int u_put(char *s,int u) {
|
54
|
+
unsigned char *t=(unsigned char*)s;
|
55
|
+
if(!(u&B1)) {v1(t,u); return 1;}
|
56
|
+
if(!(u&B2)) {v2(t,u); return 2;}
|
57
|
+
if(!(u&B3)) {v3(t,u); return 3;}
|
58
|
+
if(!(u&B4)) {v4(t,u); return 4;}
|
59
|
+
if(!(u&B5)) {v5(t,u); return 5;}
|
60
|
+
if(!(u&B6)) {v6(t,u); return 6;}
|
61
|
+
return 0;
|
62
|
+
}
|
63
|
+
|
64
|
+
int u_strlen(char *s) {int n=0; while(*(s+n)) ++n; return u_strnlen(s,n);}
|
65
|
+
int u_strnlen(char *s,int n) {
|
66
|
+
int i,len=0,u;
|
67
|
+
char *end=s+n;
|
68
|
+
for(;;) {
|
69
|
+
if(s==end) break;
|
70
|
+
i=u_get(&u,s);
|
71
|
+
if(i==0) {len=-1; break;}
|
72
|
+
s+=i;
|
73
|
+
if(s>end) {len=-1; break;}
|
74
|
+
++len;
|
75
|
+
}
|
76
|
+
return len;
|
77
|
+
}
|
78
|
+
|
79
|
+
int u_in_ranges(int u,int r[][2],int len) {
|
80
|
+
int n=0,m=len-1,i;
|
81
|
+
for(;;) {
|
82
|
+
if(n>m) return 0;
|
83
|
+
i=(n+m)/2;
|
84
|
+
if(u<r[i][0]) m=i-1;
|
85
|
+
else if(u>r[i][1]) n=i+1;
|
86
|
+
else return 1;
|
87
|
+
}
|
88
|
+
}
|
data/ext/rnv/src/u.h
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
/* $Id: u.h,v 1.15 2004/01/15 23:47:45 dvd Exp $ */
|
2
|
+
|
3
|
+
#ifndef U_H
|
4
|
+
#define U_H 1
|
5
|
+
|
6
|
+
#define U_MAXLEN 6
|
7
|
+
|
8
|
+
/* returns BOM length if the string starts with BOM */
|
9
|
+
extern int u_bom(char *s,int n);
|
10
|
+
|
11
|
+
/* computes a unicode character u off the head of s;
|
12
|
+
returns number of bytes read. 0 means error.
|
13
|
+
*/
|
14
|
+
extern int u_get(int *up,char *s);
|
15
|
+
|
16
|
+
/* encodes u in utf-8, returns number of octets taken */
|
17
|
+
extern int u_put(char *s,int u);
|
18
|
+
|
19
|
+
/* number of unicode characters in the string; -1 means error */
|
20
|
+
extern int u_strlen(char *s);
|
21
|
+
extern int u_strnlen(char *s,int n);
|
22
|
+
|
23
|
+
/* checks whether a character falls within one of sorted ranges */
|
24
|
+
extern int u_in_ranges(int u,int r[][2],int len);
|
25
|
+
|
26
|
+
#endif
|
data/ext/rnv/src/xcl.c
ADDED
@@ -0,0 +1,472 @@
|
|
1
|
+
/* rnv command line tool keeped for reference, actually not used */
|
2
|
+
/* $Id: xcl.c,v 1.44 2006/01/29 18:29:57 dvd Exp $ */
|
3
|
+
#include "type.h"
|
4
|
+
|
5
|
+
#include <stdlib.h>
|
6
|
+
#include <stdarg.h>
|
7
|
+
#include <fcntl.h> /*open,close*/
|
8
|
+
#include <sys/types.h>
|
9
|
+
#include <unistd.h> /*open,read,close*/
|
10
|
+
#include <string.h> /*strerror*/
|
11
|
+
#include <errno.h>
|
12
|
+
#include <assert.h>
|
13
|
+
#include <expat.h>
|
14
|
+
#include "m.h"
|
15
|
+
#include "s.h"
|
16
|
+
#include "erbit.h"
|
17
|
+
#include "drv.h"
|
18
|
+
#include "rnl.h"
|
19
|
+
#include "rnv.h"
|
20
|
+
#include "rnx.h"
|
21
|
+
#include "ll.h"
|
22
|
+
#include "er.h"
|
23
|
+
|
24
|
+
#define RNV_VERSION "1.7.8"
|
25
|
+
|
26
|
+
extern int rn_notAllowed, rx_compact, drv_compact;
|
27
|
+
|
28
|
+
typedef struct xcl_st {
|
29
|
+
int peipe;
|
30
|
+
int verbose;
|
31
|
+
int nexp;
|
32
|
+
int rnck;
|
33
|
+
char * xml;
|
34
|
+
int start;
|
35
|
+
int current;
|
36
|
+
int previous;
|
37
|
+
int lastline;
|
38
|
+
int lastcol;
|
39
|
+
int level;
|
40
|
+
int ok;
|
41
|
+
char * text;
|
42
|
+
int len_txt;
|
43
|
+
int n_txt;
|
44
|
+
|
45
|
+
rnv_t *rnv;
|
46
|
+
drv_st_t *drv_st;
|
47
|
+
rn_st_t *rn_st;
|
48
|
+
rx_st_t *rx_st;
|
49
|
+
} xcl_st_t;
|
50
|
+
|
51
|
+
#define LEN_T XCL_LEN_T
|
52
|
+
#define LIM_T XCL_LIM_T
|
53
|
+
|
54
|
+
#define BUFSIZE 1024
|
55
|
+
|
56
|
+
/* maximum number of candidates to display */
|
57
|
+
#define NEXP 16
|
58
|
+
|
59
|
+
#define XCL_ER_IO 0
|
60
|
+
#define XCL_ER_XML 1
|
61
|
+
#define XCL_ER_XENT 2
|
62
|
+
|
63
|
+
#define PIXGFILE "davidashen-net-xg-file"
|
64
|
+
#define PIXGPOS "davidashen-net-xg-pos"
|
65
|
+
|
66
|
+
static XML_Parser expat = NULL;
|
67
|
+
static int mixed = 0;
|
68
|
+
static char *xgfile = NULL, *xgpos = NULL;
|
69
|
+
|
70
|
+
#define err(msg) (*rnv->verror_handler)(rnv,erno,msg "\n", ap);
|
71
|
+
static void verror_handler(rnv_t *rnv, xcl_st_t *xcl_st, rnx_st_t *rnx_st, int erno, va_list ap)
|
72
|
+
{
|
73
|
+
if (erno & ERBIT_RNL)
|
74
|
+
{
|
75
|
+
rnl_default_verror_handler(rnv, erno & ~ERBIT_RNL, ap);
|
76
|
+
}
|
77
|
+
else
|
78
|
+
{
|
79
|
+
int line = XML_GetCurrentLineNumber(expat), col = XML_GetCurrentColumnNumber(expat);
|
80
|
+
if (line != xcl_st->lastline || col != xcl_st->lastcol)
|
81
|
+
{
|
82
|
+
xcl_st->lastline = line;
|
83
|
+
xcl_st->lastcol = col;
|
84
|
+
if (xgfile)
|
85
|
+
(*er_printf)("%s:%s: error: ", xgfile, xgpos);
|
86
|
+
else
|
87
|
+
(*er_printf)("%s:%i:%i: error: ", xcl_st->xml, line, col);
|
88
|
+
if (erno & ERBIT_RNV)
|
89
|
+
{
|
90
|
+
rnv_default_verror_handler(rnv, erno & ~ERBIT_RNV, ap);
|
91
|
+
if (xcl_st->nexp)
|
92
|
+
{
|
93
|
+
int req = 2, i = 0;
|
94
|
+
char *s;
|
95
|
+
while (req--)
|
96
|
+
{
|
97
|
+
rnx_expected(rnv, rnx_st, xcl_st->previous, req);
|
98
|
+
if (i == rnv->rnx_n_exp)
|
99
|
+
continue;
|
100
|
+
if (rnv->rnx_n_exp > xcl_st->nexp)
|
101
|
+
break;
|
102
|
+
(*er_printf)((char *)(req ? "required:\n" : "allowed:\n"));
|
103
|
+
for (; i != rnv->rnx_n_exp; ++i)
|
104
|
+
{
|
105
|
+
(*er_printf)("\t%s\n", s = rnx_p2str(rnv, rnv->rnx_exp[i]));
|
106
|
+
m_free(s);
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
else
|
112
|
+
{
|
113
|
+
switch (erno)
|
114
|
+
{
|
115
|
+
case XCL_ER_IO:
|
116
|
+
err("%s");
|
117
|
+
break;
|
118
|
+
case XCL_ER_XML:
|
119
|
+
err("%s");
|
120
|
+
break;
|
121
|
+
case XCL_ER_XENT:
|
122
|
+
err("pipe through xx to expand external entities");
|
123
|
+
break;
|
124
|
+
default:
|
125
|
+
assert(0);
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
static void verror_handler_rnl(rnv_t *rnv, xcl_st_t *xcl_st, rnx_st_t *rnx_st, int erno, va_list ap) { verror_handler(rnv, xcl_st, rnx_st, erno | ERBIT_RNL, ap); }
|
133
|
+
static void verror_handler_rnv(rnv_t *rnv, xcl_st_t *xcl_st, rnx_st_t *rnx_st, int erno, va_list ap) { verror_handler(rnv, xcl_st, rnx_st, erno | ERBIT_RNV, ap); }
|
134
|
+
|
135
|
+
static void windup(xcl_st_t *xcl_st);
|
136
|
+
static void init(rnv_t *rnv, xcl_st_t *xcl_st, rn_st_t *rn_st, rnd_st_t *rnd_st, rnc_st_t *rnc_st, rnx_st_t *rnx_st, drv_st_t *drv_st, rx_st_t *rx_st)
|
137
|
+
{
|
138
|
+
rnv->verror_handler=&verror_default_handler;
|
139
|
+
rnl_init(rnv, rn_st, rnd_st, rnc_st);
|
140
|
+
//rnl_verror_handler = &verror_handler_rnl;
|
141
|
+
rnv_init(rnv, drv_st, rn_st, rx_st);
|
142
|
+
//rnv_verror_handler = &verror_handler_rnv;
|
143
|
+
rnx_init(rnv, rnx_st);
|
144
|
+
xcl_st->text = (char *)m_alloc(xcl_st->len_txt = LEN_T, sizeof(char));
|
145
|
+
windup(xcl_st);
|
146
|
+
}
|
147
|
+
|
148
|
+
static void clear(xcl_st_t *xcl_st)
|
149
|
+
{
|
150
|
+
if (xcl_st->len_txt > LIM_T)
|
151
|
+
{
|
152
|
+
m_free(xcl_st->text);
|
153
|
+
xcl_st->text = (char *)m_alloc(xcl_st->len_txt = LEN_T, sizeof(char));
|
154
|
+
}
|
155
|
+
windup(xcl_st);
|
156
|
+
}
|
157
|
+
|
158
|
+
static void windup(xcl_st_t *xcl_st)
|
159
|
+
{
|
160
|
+
xcl_st->text[xcl_st->n_txt = 0] = '\0';
|
161
|
+
xcl_st->level = 0;
|
162
|
+
xcl_st->lastline = xcl_st->lastcol = -1;
|
163
|
+
}
|
164
|
+
|
165
|
+
static void error_handler(rnv_t *rnv, xcl_st_t *xcl_st, rnx_st_t *rnx_st, int erno, ...)
|
166
|
+
{
|
167
|
+
va_list ap;
|
168
|
+
va_start(ap, erno);
|
169
|
+
verror_handler(rnv, xcl_st, rnx_st, erno, ap);
|
170
|
+
va_end(ap);
|
171
|
+
}
|
172
|
+
|
173
|
+
static void flush_text(rnv_t *rnv, xcl_st_t *xcl_st, drv_st_t *drv_st, rn_st_t *rn_st, rx_st_t *rx_st)
|
174
|
+
{
|
175
|
+
xcl_st->ok = rnv_text(rnv, drv_st, rn_st, rx_st, &xcl_st->current, &xcl_st->previous, xcl_st->text, xcl_st->n_txt, mixed) && xcl_st->ok;
|
176
|
+
xcl_st->text[xcl_st->n_txt = 0] = '\0';
|
177
|
+
}
|
178
|
+
|
179
|
+
static void start_element(void *userData, const char *name, const char **attrs)
|
180
|
+
{
|
181
|
+
xcl_st_t *xcl_st = (xcl_st_t *)userData;
|
182
|
+
rnv_t *rnv = xcl_st->rnv;
|
183
|
+
drv_st_t *drv_st = xcl_st->drv_st;
|
184
|
+
rn_st_t *rn_st = xcl_st->rn_st;
|
185
|
+
rx_st_t *rx_st = xcl_st->rx_st;
|
186
|
+
|
187
|
+
if (xcl_st->current != rnv->rn_notAllowed)
|
188
|
+
{
|
189
|
+
mixed = 1;
|
190
|
+
flush_text(rnv, xcl_st, drv_st, rn_st, rx_st);
|
191
|
+
xcl_st->ok = rnv_start_tag(rnv, drv_st, rn_st, rx_st, &xcl_st->current, &xcl_st->previous, (char *)name, (char **)attrs) && xcl_st->ok;
|
192
|
+
mixed = 0;
|
193
|
+
}
|
194
|
+
else
|
195
|
+
{
|
196
|
+
++xcl_st->level;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
static void end_element(void *userData, const char *name)
|
201
|
+
{
|
202
|
+
xcl_st_t *xcl_st = (xcl_st_t *)userData;
|
203
|
+
rnv_t *rnv = xcl_st->rnv;
|
204
|
+
drv_st_t *drv_st = xcl_st->drv_st;
|
205
|
+
rn_st_t *rn_st = xcl_st->rn_st;
|
206
|
+
rx_st_t *rx_st = xcl_st->rx_st;
|
207
|
+
|
208
|
+
if (xcl_st->current != rnv->rn_notAllowed)
|
209
|
+
{
|
210
|
+
flush_text(rnv, xcl_st, drv_st, rn_st, rx_st);
|
211
|
+
xcl_st->ok = rnv_end_tag(rnv, drv_st, rn_st, &xcl_st->current, &xcl_st->previous, (char *)name) && xcl_st->ok;
|
212
|
+
mixed = 1;
|
213
|
+
}
|
214
|
+
else
|
215
|
+
{
|
216
|
+
if (xcl_st->level == 0)
|
217
|
+
xcl_st->current = xcl_st->previous;
|
218
|
+
else
|
219
|
+
--xcl_st->level;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
static void characters(void *userData, const char *s, int len)
|
224
|
+
{
|
225
|
+
xcl_st_t *xcl_st = (xcl_st_t *)userData;
|
226
|
+
rnv_t *rnv = xcl_st->rnv;
|
227
|
+
|
228
|
+
if (xcl_st->current != rnv->rn_notAllowed)
|
229
|
+
{
|
230
|
+
int newlen_txt = xcl_st->n_txt + len + 1;
|
231
|
+
if (newlen_txt <= LIM_T && LIM_T < xcl_st->len_txt)
|
232
|
+
newlen_txt = LIM_T;
|
233
|
+
else if (newlen_txt < xcl_st->len_txt)
|
234
|
+
newlen_txt = xcl_st->len_txt;
|
235
|
+
if (xcl_st->len_txt != newlen_txt)
|
236
|
+
xcl_st->text = (char *)m_stretch(xcl_st->text, xcl_st->len_txt = newlen_txt, xcl_st->n_txt, sizeof(char));
|
237
|
+
memcpy(xcl_st->text + xcl_st->n_txt, s, len);
|
238
|
+
xcl_st->n_txt += len;
|
239
|
+
xcl_st->text[xcl_st->n_txt] = '\0'; /* '\0' guarantees that the text is bounded, and strto[ld] work for data */
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
static void processingInstruction(void *userData,
|
244
|
+
const char *target, const char *data)
|
245
|
+
{
|
246
|
+
if (strcmp(PIXGFILE, target) == 0)
|
247
|
+
{
|
248
|
+
if (xgfile)
|
249
|
+
m_free(xgfile);
|
250
|
+
xgfile = s_clone((char *)data);
|
251
|
+
}
|
252
|
+
else if (strcmp(PIXGPOS, target) == 0)
|
253
|
+
{
|
254
|
+
if (xgpos)
|
255
|
+
m_free(xgpos);
|
256
|
+
xgpos = s_clone((char *)data);
|
257
|
+
*strchr(xgpos, ' ') = ':';
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
static int pipeout(rnv_t *rnv, xcl_st_t *xcl_st, rnx_st_t *rnx_st, void *buf, int len)
|
262
|
+
{
|
263
|
+
int ofs = 0, iw, lenw = len;
|
264
|
+
for (;;)
|
265
|
+
{
|
266
|
+
if ((iw = write(1, (char *)buf + ofs, lenw)) == -1)
|
267
|
+
{
|
268
|
+
error_handler(rnv, xcl_st, rnx_st, XCL_ER_IO, strerror(errno));
|
269
|
+
return 0;
|
270
|
+
}
|
271
|
+
ofs += iw;
|
272
|
+
lenw -= iw;
|
273
|
+
if (lenw == 0)
|
274
|
+
return 1;
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
static int process(rnv_t *rnv, xcl_st_t *xcl_st, rnx_st_t *rnx_st, int fd)
|
279
|
+
{
|
280
|
+
void *buf;
|
281
|
+
int len;
|
282
|
+
for (;;)
|
283
|
+
{
|
284
|
+
buf = XML_GetBuffer(expat, BUFSIZE);
|
285
|
+
len = read(fd, buf, BUFSIZE);
|
286
|
+
if (len < 0)
|
287
|
+
{
|
288
|
+
error_handler(rnv, xcl_st, rnx_st, XCL_ER_IO, xcl_st->xml, strerror(errno));
|
289
|
+
goto ERROR;
|
290
|
+
}
|
291
|
+
if (xcl_st->peipe)
|
292
|
+
xcl_st->peipe = xcl_st->peipe && pipeout(rnv, xcl_st, rnx_st, buf, len);
|
293
|
+
if (!XML_ParseBuffer(expat, len, len == 0))
|
294
|
+
goto PARSE_ERROR;
|
295
|
+
if (len == 0)
|
296
|
+
break;
|
297
|
+
}
|
298
|
+
return xcl_st->ok;
|
299
|
+
|
300
|
+
PARSE_ERROR:
|
301
|
+
error_handler(rnv, xcl_st, rnx_st, XCL_ER_XML, XML_ErrorString(XML_GetErrorCode(expat)));
|
302
|
+
while (xcl_st->peipe && (len = read(fd, buf, BUFSIZE)) != 0)
|
303
|
+
xcl_st->peipe = xcl_st->peipe && pipeout(rnv, xcl_st, rnx_st, buf, len);
|
304
|
+
ERROR:
|
305
|
+
return 0;
|
306
|
+
}
|
307
|
+
|
308
|
+
static int externalEntityRef(XML_Parser p, const char *context,
|
309
|
+
const char *base, const char *systemId, const char *publicId)
|
310
|
+
{
|
311
|
+
//error_handler(rnv, xcl_st, rnx_st, XCL_ER_XENT);
|
312
|
+
return 1;
|
313
|
+
}
|
314
|
+
|
315
|
+
static void validate(rnv_t *rnv, xcl_st_t *xcl_st, drv_st_t *drv_st, rn_st_t *rn_st, rnx_st_t *rnx_st, int fd)
|
316
|
+
{
|
317
|
+
xcl_st->previous = xcl_st->current = xcl_st->start;
|
318
|
+
expat = XML_ParserCreateNS(NULL, ':');
|
319
|
+
XML_SetParamEntityParsing(expat, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
320
|
+
XML_SetElementHandler(expat, &start_element, &end_element);
|
321
|
+
XML_SetCharacterDataHandler(expat, &characters);
|
322
|
+
XML_SetExternalEntityRefHandler(expat, &externalEntityRef);
|
323
|
+
XML_SetProcessingInstructionHandler(expat, &processingInstruction);
|
324
|
+
XML_SetUserData(expat, xcl_st);
|
325
|
+
xcl_st->ok = process(rnv, xcl_st, rnx_st, fd);
|
326
|
+
XML_ParserFree(expat);
|
327
|
+
}
|
328
|
+
|
329
|
+
static void version(void) { (*er_printf)("rnv version %s\n", RNV_VERSION); }
|
330
|
+
static void usage(void) { (*er_printf)("usage: rnv {-[qnspcvh?]} schema.rnc {document.xml}\n"); }
|
331
|
+
|
332
|
+
int main(int argc, char **argv)
|
333
|
+
{
|
334
|
+
rnv_t *rnv;
|
335
|
+
rn_st_t *rn_st;
|
336
|
+
rnc_st_t *rnc_st;
|
337
|
+
rnx_st_t *rnx_st;
|
338
|
+
drv_st_t *drv_st;
|
339
|
+
rx_st_t *rx_st;
|
340
|
+
rnd_st_t *rnd_st;
|
341
|
+
xcl_st_t *xcl_st;
|
342
|
+
|
343
|
+
rnv = malloc(sizeof(rnv_t));
|
344
|
+
rn_st = malloc(sizeof(rn_st_t));
|
345
|
+
rnc_st = malloc(sizeof(rnc_st_t));
|
346
|
+
rnx_st = malloc(sizeof(rnx_st_t));
|
347
|
+
drv_st = malloc(sizeof(drv_st_t));
|
348
|
+
rx_st = malloc(sizeof(rx_st_t));
|
349
|
+
rnd_st = malloc(sizeof(rnd_st_t));
|
350
|
+
xcl_st = malloc(sizeof(xcl_st_t));
|
351
|
+
|
352
|
+
xcl_st->rnv = rnv;
|
353
|
+
xcl_st->drv_st = drv_st;
|
354
|
+
xcl_st->rn_st = rn_st;
|
355
|
+
xcl_st->rx_st = rx_st;
|
356
|
+
|
357
|
+
init(rnv, xcl_st, rn_st, rnc_st, rnd_st, rnx_st, drv_st, rx_st);
|
358
|
+
|
359
|
+
xcl_st->peipe = 0;
|
360
|
+
xcl_st->verbose = 1;
|
361
|
+
xcl_st->nexp = NEXP;
|
362
|
+
xcl_st->rnck = 0;
|
363
|
+
while (*(++argv) && **argv == '-')
|
364
|
+
{
|
365
|
+
int i = 1;
|
366
|
+
for (;;)
|
367
|
+
{
|
368
|
+
switch (*(*argv + i))
|
369
|
+
{
|
370
|
+
case '\0':
|
371
|
+
goto END_OF_OPTIONS;
|
372
|
+
case 'q':
|
373
|
+
xcl_st->verbose = 0;
|
374
|
+
xcl_st->nexp = 0;
|
375
|
+
break;
|
376
|
+
case 'n':
|
377
|
+
if (*(argv + 1))
|
378
|
+
xcl_st->nexp = atoi(*(++argv));
|
379
|
+
goto END_OF_OPTIONS;
|
380
|
+
case 's':
|
381
|
+
rnv->drv_compact = 1;
|
382
|
+
rnv->rx_compact = 1;
|
383
|
+
break;
|
384
|
+
case 'p':
|
385
|
+
xcl_st->peipe = 1;
|
386
|
+
break;
|
387
|
+
case 'c':
|
388
|
+
xcl_st->rnck = 1;
|
389
|
+
break;
|
390
|
+
#if DXL_EXC
|
391
|
+
case 'd':
|
392
|
+
dxl_cmd = *(argv + 1);
|
393
|
+
if (*(argv + 1))
|
394
|
+
++argv;
|
395
|
+
goto END_OF_OPTIONS;
|
396
|
+
#endif
|
397
|
+
#if DSL_SCM
|
398
|
+
case 'e':
|
399
|
+
dsl_ld(*(argv + 1));
|
400
|
+
if (*(argv + 1))
|
401
|
+
++argv;
|
402
|
+
goto END_OF_OPTIONS;
|
403
|
+
#endif
|
404
|
+
case 'v':
|
405
|
+
version();
|
406
|
+
break;
|
407
|
+
case 'h':
|
408
|
+
case '?':
|
409
|
+
usage();
|
410
|
+
return 1;
|
411
|
+
default:
|
412
|
+
(*er_printf)("unknown option '-%c'\n", *(*argv + i));
|
413
|
+
break;
|
414
|
+
}
|
415
|
+
++i;
|
416
|
+
}
|
417
|
+
END_OF_OPTIONS:;
|
418
|
+
}
|
419
|
+
|
420
|
+
if (!*(argv))
|
421
|
+
{
|
422
|
+
usage();
|
423
|
+
return 1;
|
424
|
+
}
|
425
|
+
|
426
|
+
if ((xcl_st->ok = xcl_st->start = rnl_fn(rnv, rnc_st, rn_st, rnd_st, *(argv++))))
|
427
|
+
{
|
428
|
+
if (*argv)
|
429
|
+
{
|
430
|
+
do
|
431
|
+
{
|
432
|
+
int fd;
|
433
|
+
xcl_st->xml = *argv;
|
434
|
+
if ((fd = open(xcl_st->xml, O_RDONLY)) == -1)
|
435
|
+
{
|
436
|
+
(*er_printf)("I/O error (%s): %s\n", xcl_st->xml, strerror(errno));
|
437
|
+
xcl_st->ok = 0;
|
438
|
+
continue;
|
439
|
+
}
|
440
|
+
if (xcl_st->verbose)
|
441
|
+
(*er_printf)("%s\n", xcl_st->xml);
|
442
|
+
validate(rnv, xcl_st, drv_st, rn_st, rnx_st, fd);
|
443
|
+
close(fd);
|
444
|
+
clear(xcl_st);
|
445
|
+
} while (*(++argv));
|
446
|
+
if (!xcl_st->ok && xcl_st->verbose)
|
447
|
+
(*er_printf)("error: some documents are invalid\n");
|
448
|
+
}
|
449
|
+
else
|
450
|
+
{
|
451
|
+
if (!xcl_st->rnck)
|
452
|
+
{
|
453
|
+
xcl_st->xml = "stdin";
|
454
|
+
validate(rnv, xcl_st, drv_st, rn_st, rnx_st, 0);
|
455
|
+
clear(xcl_st);
|
456
|
+
if (!xcl_st->ok && xcl_st->verbose)
|
457
|
+
(*er_printf)("error: invalid input\n");
|
458
|
+
}
|
459
|
+
}
|
460
|
+
}
|
461
|
+
|
462
|
+
free(rnv);
|
463
|
+
free(rn_st);
|
464
|
+
free(rnc_st);
|
465
|
+
free(rnx_st);
|
466
|
+
free(drv_st);
|
467
|
+
free(rx_st);
|
468
|
+
free(rnd_st);
|
469
|
+
free(xcl_st);
|
470
|
+
|
471
|
+
return xcl_st->ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
472
|
+
}
|