ruby_rnv 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/ext/rnv/extconf.rb +15 -0
  4. data/ext/rnv/ruby_rnv.c +742 -0
  5. data/ext/rnv/src/ary.c +78 -0
  6. data/ext/rnv/src/ary.h +10 -0
  7. data/ext/rnv/src/drv.c +472 -0
  8. data/ext/rnv/src/drv.h +35 -0
  9. data/ext/rnv/src/er.c +15 -0
  10. data/ext/rnv/src/er.h +16 -0
  11. data/ext/rnv/src/erbit.h +14 -0
  12. data/ext/rnv/src/ht.c +90 -0
  13. data/ext/rnv/src/ht.h +22 -0
  14. data/ext/rnv/src/ll.h +43 -0
  15. data/ext/rnv/src/m.c +60 -0
  16. data/ext/rnv/src/m.h +10 -0
  17. data/ext/rnv/src/rn.c +569 -0
  18. data/ext/rnv/src/rn.h +150 -0
  19. data/ext/rnv/src/rnc.c +1191 -0
  20. data/ext/rnv/src/rnc.h +68 -0
  21. data/ext/rnv/src/rnd.c +436 -0
  22. data/ext/rnv/src/rnd.h +25 -0
  23. data/ext/rnv/src/rnl.c +62 -0
  24. data/ext/rnv/src/rnl.h +18 -0
  25. data/ext/rnv/src/rnv.c +158 -0
  26. data/ext/rnv/src/rnv.h +30 -0
  27. data/ext/rnv/src/rnx.c +153 -0
  28. data/ext/rnv/src/rnx.h +16 -0
  29. data/ext/rnv/src/rx.c +749 -0
  30. data/ext/rnv/src/rx.h +43 -0
  31. data/ext/rnv/src/rx_cls_ranges.c +126 -0
  32. data/ext/rnv/src/rx_cls_u.c +262 -0
  33. data/ext/rnv/src/s.c +103 -0
  34. data/ext/rnv/src/s.h +32 -0
  35. data/ext/rnv/src/sc.c +62 -0
  36. data/ext/rnv/src/sc.h +26 -0
  37. data/ext/rnv/src/type.h +121 -0
  38. data/ext/rnv/src/u.c +88 -0
  39. data/ext/rnv/src/u.h +26 -0
  40. data/ext/rnv/src/xcl.c +472 -0
  41. data/ext/rnv/src/xmlc.c +20 -0
  42. data/ext/rnv/src/xmlc.h +16 -0
  43. data/ext/rnv/src/xsd.c +789 -0
  44. data/ext/rnv/src/xsd.h +27 -0
  45. data/ext/rnv/src/xsd_tm.c +100 -0
  46. data/ext/rnv/src/xsd_tm.h +15 -0
  47. data/lib/rnv.rb +2 -0
  48. data/lib/rnv/ox_sax_document.rb +84 -0
  49. data/lib/rnv/validator.rb +104 -0
  50. metadata +175 -0
data/ext/rnv/src/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
+ }