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/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
@@ -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
+ }