-
Notifications
You must be signed in to change notification settings - Fork 5
/
rnv.c
161 lines (143 loc) · 4.45 KB
/
rnv.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* $Id$ */
#include <string.h> /*strncpy,strrchr*/
#include <assert.h>
#include "m.h"
#include "xmlc.h" /*xmlc_white_space*/
#include "erbit.h"
#include "drv.h"
#include "er.h"
#include "rnv.h"
extern int rn_notAllowed;
#define err(msg) (*er_vprintf)(msg"\n",ap);
void rnv_default_verror_handler(int erno,va_list ap) {
if(erno&ERBIT_DRV) {
drv_default_verror_handler(erno&~ERBIT_DRV,ap);
} else {
switch(erno) {
case RNV_ER_ELEM: err("element %s^%s not allowed"); break;
case RNV_ER_AKEY: err("attribute %s^%s not allowed"); break;
case RNV_ER_AVAL: err("attribute %s^%s with invalid value \"%s\""); break;
case RNV_ER_EMIS: err("incomplete content"); break;
case RNV_ER_AMIS: err("missing attributes of %s^%s"); break;
case RNV_ER_UFIN: err("unfinished content of element %s^%s"); break;
case RNV_ER_TEXT: err("invalid data or text not allowed"); break;
case RNV_ER_NOTX: err("text not allowed"); break;
default: assert(0);
}
}
}
void (*rnv_verror_handler)(int erno,va_list ap)=&rnv_default_verror_handler;
static void error_handler(int erno,...) {
va_list ap; va_start(ap,erno); (*rnv_verror_handler)(erno,ap); va_end(ap);
}
static void verror_handler_drv(int erno,va_list ap) {(*rnv_verror_handler)(erno|ERBIT_DRV,ap);}
static void windup(void);
static int initialized=0;
void rnv_init(void) {
if(!initialized) {initialized=1;
drv_init(); drv_verror_handler=&verror_handler_drv;
windup();
}
}
void rnv_clear(void) {
windup();
}
static void windup(void) {
}
static char *qname_open(char **surip,char **snamep,char *name) {
char *sep;
if((sep=strrchr(name,':'))) {
*snamep=sep+1; *surip=name; *sep='\0';
} else {
*snamep=name; while(*name) ++name; *surip=name;
}
return sep; /* NULL if no namespace */
}
static void qname_close(char *sep) {if(sep) *sep=':';}
static int whitespace(char *text,int n_txt) {
char *s=text,*end=text+n_txt;
for(;;) {
if(s==end) return 1;
if(!xmlc_white_space(*(s++))) return 0;
}
}
int rnv_text(int *curp,int *prevp,char *text,int n_txt,int mixed) {
int ok=1;
if(mixed) {
if(!whitespace(text,n_txt)) {
*curp=drv_mixed_text(*prevp=*curp);
if(*curp==rn_notAllowed) { ok=0;
*curp=drv_mixed_text_recover(*prevp);
error_handler(RNV_ER_NOTX);
}
}
} else {
*curp=drv_text(*prevp=*curp,text,n_txt);
if(*curp==rn_notAllowed) { ok=0;
*curp=drv_text_recover(*prevp,text,n_txt);
error_handler(RNV_ER_TEXT);
}
}
return ok;
}
int rnv_start_tag_open(int *curp,int *prevp,char *name) {
int ok=1; char *suri,*sname,*sep;
sep=qname_open(&suri,&sname,name);
*curp=drv_start_tag_open(*prevp=*curp,suri,sname);
if(*curp==rn_notAllowed) { ok=0;
*curp=drv_start_tag_open_recover(*prevp,suri,sname);
error_handler(*curp==rn_notAllowed?RNV_ER_ELEM:RNV_ER_EMIS,suri,sname);
}
qname_close(sep);
return ok;
}
int rnv_attribute(int *curp,int *prevp,char *name,char *val) {
int ok=1; char *suri,*sname,*sep;
sep=qname_open(&suri,&sname,name);
*curp=drv_attribute_open(*prevp=*curp,suri,sname);
if(*curp==rn_notAllowed) { ok=0;
*curp=drv_attribute_open_recover(*prevp,suri,sname);
error_handler(RNV_ER_AKEY,suri,sname);
} else {
*curp=drv_text(*prevp=*curp,(char*)val,strlen(val));
if(*curp==rn_notAllowed || (*curp=drv_attribute_close(*prevp=*curp))==rn_notAllowed) { ok=0;
*curp=drv_attribute_close_recover(*prevp);
error_handler(RNV_ER_AVAL,suri,sname,val);
}
}
qname_close(sep);
return ok;
}
int rnv_start_tag_close(int *curp,int *prevp,char *name) {
int ok=1; char *suri,*sname,*sep;
*curp=drv_start_tag_close(*prevp=*curp);
if(*curp==rn_notAllowed) { ok=0;
*curp=drv_start_tag_close_recover(*prevp);
sep=qname_open(&suri,&sname,name);
error_handler(RNV_ER_AMIS,suri,sname);
qname_close(sep);
}
return ok;
}
int rnv_start_tag(int *curp,int *prevp,char *name,char **attrs) {
int ok=1;
ok=rnv_start_tag_open(curp,prevp,name)&&ok;
while(*curp!=rn_notAllowed) {
if(!(*attrs)) break;
ok = rnv_attribute(curp,prevp,*attrs,*(attrs+1))&&ok;
attrs+=2;
}
if(*curp!=rn_notAllowed) ok=rnv_start_tag_close(curp,prevp,name)&&ok;
return ok;
}
int rnv_end_tag(int *curp,int *prevp,char *name) {
int ok=1; char *suri,*sname,*sep;
*curp=drv_end_tag(*prevp=*curp);
if(*curp==rn_notAllowed) { ok=0;
sep=qname_open(&suri,&sname,name);
error_handler(RNV_ER_UFIN,suri,sname);
qname_close(sep);
*curp=drv_end_tag_recover(*prevp);
}
return ok;
}