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/xmlc.c
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
/* $Id: xmlc.c,v 1.3 2003/12/22 20:05:12 dvd Exp $ */
|
2
|
+
|
3
|
+
#include "u.h"
|
4
|
+
#include "xmlc.h"
|
5
|
+
|
6
|
+
/* sorted range arrays */
|
7
|
+
int BASE_CHAR[][2]={{0x41,0x5a},{0x61,0x7a},{0xc0,0xd6},{0xd8,0xf6},{0xf8,0xff},{0x100,0x131},{0x134,0x13e},{0x141,0x148},{0x14a,0x17e},{0x180,0x1c3},{0x1cd,0x1f0},{0x1f4,0x1f5},{0x1fa,0x217},{0x250,0x2a8},{0x2bb,0x2c1},{0x386,0x386},{0x388,0x38a},{0x38c,0x38c},{0x38e,0x3a1},{0x3a3,0x3ce},{0x3d0,0x3d6},{0x3da,0x3da},{0x3dc,0x3dc},{0x3de,0x3de},{0x3e0,0x3e0},{0x3e2,0x3f3},{0x401,0x40c},{0x40e,0x44f},{0x451,0x45c},{0x45e,0x481},{0x490,0x4c4},{0x4c7,0x4c8},{0x4cb,0x4cc},{0x4d0,0x4eb},{0x4ee,0x4f5},{0x4f8,0x4f9},{0x531,0x556},{0x559,0x559},{0x561,0x586},{0x5d0,0x5ea},{0x5f0,0x5f2},{0x621,0x63a},{0x641,0x64a},{0x671,0x6b7},{0x6ba,0x6be},{0x6c0,0x6ce},{0x6d0,0x6d3},{0x6d5,0x6d5},{0x6e5,0x6e6},{0x905,0x939},{0x93d,0x93d},{0x958,0x961},{0x985,0x98c},{0x98f,0x990},{0x993,0x9a8},{0x9aa,0x9b0},{0x9b2,0x9b2},{0x9b6,0x9b9},{0x9dc,0x9dd},{0x9df,0x9e1},{0x9f0,0x9f1},{0xa05,0xa0a},{0xa0f,0xa10},{0xa13,0xa28},{0xa2a,0xa30},{0xa32,0xa33},{0xa35,0xa36},{0xa38,0xa39},{0xa59,0xa5c},{0xa5e,0xa5e},{0xa72,0xa74},{0xa85,0xa8b},{0xa8d,0xa8d},{0xa8f,0xa91},{0xa93,0xaa8},{0xaaa,0xab0},{0xab2,0xab3},{0xab5,0xab9},{0xabd,0xabd},{0xae0,0xae0},{0xb05,0xb0c},{0xb0f,0xb10},{0xb13,0xb28},{0xb2a,0xb30},{0xb32,0xb33},{0xb36,0xb39},{0xb3d,0xb3d},{0xb5c,0xb5d},{0xb5f,0xb61},{0xb85,0xb8a},{0xb8e,0xb90},{0xb92,0xb95},{0xb99,0xb9a},{0xb9c,0xb9c},{0xb9e,0xb9f},{0xba3,0xba4},{0xba8,0xbaa},{0xbae,0xbb5},{0xbb7,0xbb9},{0xc05,0xc0c},{0xc0e,0xc10},{0xc12,0xc28},{0xc2a,0xc33},{0xc35,0xc39},{0xc60,0xc61},{0xc85,0xc8c},{0xc8e,0xc90},{0xc92,0xca8},{0xcaa,0xcb3},{0xcb5,0xcb9},{0xcde,0xcde},{0xce0,0xce1},{0xd05,0xd0c},{0xd0e,0xd10},{0xd12,0xd28},{0xd2a,0xd39},{0xd60,0xd61},{0xe01,0xe2e},{0xe30,0xe30},{0xe32,0xe33},{0xe40,0xe45},{0xe81,0xe82},{0xe84,0xe84},{0xe87,0xe88},{0xe8a,0xe8a},{0xe8d,0xe8d},{0xe94,0xe97},{0xe99,0xe9f},{0xea1,0xea3},{0xea5,0xea5},{0xea7,0xea7},{0xeaa,0xeab},{0xead,0xeae},{0xeb0,0xeb0},{0xeb2,0xeb3},{0xebd,0xebd},{0xec0,0xec4},{0xf40,0xf47},{0xf49,0xf69},{0x10a0,0x10c5},{0x10d0,0x10f6},{0x1100,0x1100},{0x1102,0x1103},{0x1105,0x1107},{0x1109,0x1109},{0x110b,0x110c},{0x110e,0x1112},{0x113c,0x113c},{0x113e,0x113e},{0x1140,0x1140},{0x114c,0x114c},{0x114e,0x114e},{0x1150,0x1150},{0x1154,0x1155},{0x1159,0x1159},{0x115f,0x1161},{0x1163,0x1163},{0x1165,0x1165},{0x1167,0x1167},{0x1169,0x1169},{0x116d,0x116e},{0x1172,0x1173},{0x1175,0x1175},{0x119e,0x119e},{0x11a8,0x11a8},{0x11ab,0x11ab},{0x11ae,0x11af},{0x11b7,0x11b8},{0x11ba,0x11ba},{0x11bc,0x11c2},{0x11eb,0x11eb},{0x11f0,0x11f0},{0x11f9,0x11f9},{0x1e00,0x1e9b},{0x1ea0,0x1ef9},{0x1f00,0x1f15},{0x1f18,0x1f1d},{0x1f20,0x1f45},{0x1f48,0x1f4d},{0x1f50,0x1f57},{0x1f59,0x1f59},{0x1f5b,0x1f5b},{0x1f5d,0x1f5d},{0x1f5f,0x1f7d},{0x1f80,0x1fb4},{0x1fb6,0x1fbc},{0x1fbe,0x1fbe},{0x1fc2,0x1fc4},{0x1fc6,0x1fcc},{0x1fd0,0x1fd3},{0x1fd6,0x1fdb},{0x1fe0,0x1fec},{0x1ff2,0x1ff4},{0x1ff6,0x1ffc},{0x2126,0x2126},{0x212a,0x212b},{0x212e,0x212e},{0x2180,0x2182},{0x3041,0x3094},{0x30a1,0x30fa},{0x3105,0x312c},{0xac00,0xd7a3}};
|
8
|
+
int IDEOGRAPHIC[][2]={{0x3007,0x3007},{0x3021,0x3029},{0x4e00,0x9fa5}};
|
9
|
+
int COMBINING_CHAR[][2]={{0x300,0x345},{0x360,0x361},{0x483,0x486},{0x591,0x5a1},{0x5a3,0x5b9},{0x5bb,0x5bd},{0x5bf,0x5bf},{0x5c1,0x5c2},{0x5c4,0x5c4},{0x64b,0x652},{0x670,0x670},{0x6d6,0x6dc},{0x6dd,0x6df},{0x6e0,0x6e4},{0x6e7,0x6e8},{0x6ea,0x6ed},{0x901,0x903},{0x93c,0x93c},{0x93e,0x94c},{0x94d,0x94d},{0x951,0x954},{0x962,0x963},{0x981,0x983},{0x9bc,0x9bc},{0x9be,0x9be},{0x9bf,0x9bf},{0x9c0,0x9c4},{0x9c7,0x9c8},{0x9cb,0x9cd},{0x9d7,0x9d7},{0x9e2,0x9e3},{0xa02,0xa02},{0xa3c,0xa3c},{0xa3e,0xa3e},{0xa3f,0xa3f},{0xa40,0xa42},{0xa47,0xa48},{0xa4b,0xa4d},{0xa70,0xa71},{0xa81,0xa83},{0xabc,0xabc},{0xabe,0xac5},{0xac7,0xac9},{0xacb,0xacd},{0xb01,0xb03},{0xb3c,0xb3c},{0xb3e,0xb43},{0xb47,0xb48},{0xb4b,0xb4d},{0xb56,0xb57},{0xb82,0xb83},{0xbbe,0xbc2},{0xbc6,0xbc8},{0xbca,0xbcd},{0xbd7,0xbd7},{0xc01,0xc03},{0xc3e,0xc44},{0xc46,0xc48},{0xc4a,0xc4d},{0xc55,0xc56},{0xc82,0xc83},{0xcbe,0xcc4},{0xcc6,0xcc8},{0xcca,0xccd},{0xcd5,0xcd6},{0xd02,0xd03},{0xd3e,0xd43},{0xd46,0xd48},{0xd4a,0xd4d},{0xd57,0xd57},{0xe31,0xe31},{0xe34,0xe3a},{0xe47,0xe4e},{0xeb1,0xeb1},{0xeb4,0xeb9},{0xebb,0xebc},{0xec8,0xecd},{0xf18,0xf19},{0xf35,0xf35},{0xf37,0xf37},{0xf39,0xf39},{0xf3e,0xf3e},{0xf3f,0xf3f},{0xf71,0xf84},{0xf86,0xf8b},{0xf90,0xf95},{0xf97,0xf97},{0xf99,0xfad},{0xfb1,0xfb7},{0xfb9,0xfb9},{0x20d0,0x20dc},{0x20e1,0x20e1},{0x302a,0x302f},{0x3099,0x3099},{0x309a,0x309a}};
|
10
|
+
int DIGIT[][2]={{0x30,0x39},{0x660,0x669},{0x6f0,0x6f9},{0x966,0x96f},{0x9e6,0x9ef},{0xa66,0xa6f},{0xae6,0xaef},{0xb66,0xb6f},{0xbe7,0xbef},{0xc66,0xc6f},{0xce6,0xcef},{0xd66,0xd6f},{0xe50,0xe59},{0xed0,0xed9},{0xf20,0xf29}};
|
11
|
+
int EXTENDER[][2]={{0xb7,0xb7},{0x2d0,0x2d1},{0x387,0x387},{0x640,0x640},{0xe46,0xe46},{0xec6,0xec6},{0x3005,0x3005},{0x3031,0x3035},{0x309d,0x309e},{0x30fc,0x30fe}};
|
12
|
+
|
13
|
+
#define isa(u,CHAR_CLASS) u_in_ranges(u,CHAR_CLASS,sizeof(CHAR_CLASS)/sizeof(int([2])))
|
14
|
+
|
15
|
+
int xmlc_white_space(int u) {return u=='\t'||u=='\n'||u=='\r'||u==' ';}
|
16
|
+
int xmlc_base_char(int u) {return isa(u,BASE_CHAR);}
|
17
|
+
int xmlc_ideographic(int u) {return isa(u,IDEOGRAPHIC);}
|
18
|
+
int xmlc_combining_char(int u) {return isa(u,COMBINING_CHAR);}
|
19
|
+
int xmlc_digit(int u) {return isa(u,DIGIT);}
|
20
|
+
int xmlc_extender(int u) {return isa(u,EXTENDER);}
|
data/ext/rnv/src/xmlc.h
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
/* $Id: xmlc.h,v 1.2 2003/12/21 22:38:28 dvd Exp $ */
|
2
|
+
|
3
|
+
#ifndef XMLC_H
|
4
|
+
#define XMLC_H 1
|
5
|
+
|
6
|
+
/* character classes required for parsing XML */
|
7
|
+
extern int xmlc_white_space(int u);
|
8
|
+
extern int xmlc_base_char(int u);
|
9
|
+
extern int xmlc_ideographic(int u);
|
10
|
+
extern int xmlc_combining_char(int u);
|
11
|
+
extern int xmlc_digit(int u);
|
12
|
+
extern int xmlc_extender(int u);
|
13
|
+
|
14
|
+
extern int u_in_ranges(int u,int r[][2],int len);
|
15
|
+
|
16
|
+
#endif
|
data/ext/rnv/src/xsd.c
ADDED
@@ -0,0 +1,789 @@
|
|
1
|
+
#include "type.h"
|
2
|
+
|
3
|
+
/* $Id: xsd.c,v 1.47 2005/01/06 21:04:06 dvd Exp $ */
|
4
|
+
|
5
|
+
#include <limits.h> /*INT_MAX*/
|
6
|
+
#include <stdlib.h> /*atof,atol,strtol*/
|
7
|
+
#include <string.h> /*strlen*/
|
8
|
+
#include <math.h> /*HUGE_VAL*/
|
9
|
+
#include <assert.h>
|
10
|
+
#include "u.h"
|
11
|
+
#include "xmlc.h"
|
12
|
+
#include "s.h"
|
13
|
+
#include "erbit.h"
|
14
|
+
#include "rx.h"
|
15
|
+
#include "xsd_tm.h"
|
16
|
+
#include "er.h"
|
17
|
+
#include "xsd.h"
|
18
|
+
|
19
|
+
#define err(msg) (*rnv->verror_handler)(rnv,erno|ERBIT_XSD,msg"\n",ap)
|
20
|
+
void xsd_default_verror_handler(rnv_t *rnv, int erno,va_list ap) {
|
21
|
+
(*er_printf)("XML Schema datatypes: ");
|
22
|
+
if(erno&ERBIT_RX) {
|
23
|
+
rx_default_verror_handler(rnv, erno&~ERBIT_RX,ap);
|
24
|
+
} else {
|
25
|
+
switch(erno) {
|
26
|
+
case XSD_ER_TYP: err("unknown type %s"); break;
|
27
|
+
case XSD_ER_PAR: err("unknown parameter %s"); break;
|
28
|
+
case XSD_ER_PARVAL: err("invalid parameter value %s=\"%s\""); break;
|
29
|
+
case XSD_ER_VAL: err("invalid typed value \"%s\" for type %s"); break;
|
30
|
+
case XSD_ER_NPAT: err("no more than 16 patterns per type are supported"); break;
|
31
|
+
case XSD_ER_WS: err("the builtin derived datatype that specifies the desired value for the whiteSpace facet should be used instead of 'whiteSpace'"); break;
|
32
|
+
case XSD_ER_ENUM: err("'value' should be used instead of 'enumeration'"); break;
|
33
|
+
default: assert(0);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
static void error_handler(rx_st_t *rx_st, int erno,...) {
|
39
|
+
va_list ap; va_start(ap,erno); (*rx_st->rnv->xsd_verror_handler)(rx_st->rnv,erno,ap); va_end(ap);
|
40
|
+
}
|
41
|
+
|
42
|
+
static void verror_handler_rx(rnv_t *rnv, int erno,va_list ap) {xsd_default_verror_handler(rnv,erno|ERBIT_RX,ap);}
|
43
|
+
|
44
|
+
static void windup(void);
|
45
|
+
void xsd_init(rx_st_t *rx_st) {
|
46
|
+
rx_st->rnv->xsd_verror_handler = &xsd_default_verror_handler;
|
47
|
+
rx_init(rx_st);
|
48
|
+
rx_st->rnv->rx_verror_handler=&verror_handler_rx;
|
49
|
+
windup();
|
50
|
+
}
|
51
|
+
|
52
|
+
void xsd_clear(void) {
|
53
|
+
windup();
|
54
|
+
}
|
55
|
+
|
56
|
+
static void windup(void) {
|
57
|
+
}
|
58
|
+
|
59
|
+
#define FCT_ENUMERATION 0
|
60
|
+
#define FCT_FRACTION_DIGITS 1
|
61
|
+
#define FCT_LENGTH 2
|
62
|
+
#define FCT_MAX_EXCLUSIVE 3
|
63
|
+
#define FCT_MAX_INCLUSIVE 4
|
64
|
+
#define FCT_MAX_LENGTH 5
|
65
|
+
#define FCT_MIN_EXCLUSIVE 6
|
66
|
+
#define FCT_MIN_INCLUSIVE 7
|
67
|
+
#define FCT_MIN_LENGTH 8
|
68
|
+
#define FCT_PATTERN 9
|
69
|
+
#define FCT_TOTAL_DIGITS 10
|
70
|
+
#define FCT_WHITE_SPACE 11
|
71
|
+
#define NFCT 12
|
72
|
+
static char *fcttab[NFCT]={
|
73
|
+
"enumeration", "fractionDigits", "length", "maxExclusive", "maxInclusive", "maxLength",
|
74
|
+
"minExclusive", "minInclusive", "minLength", "pattern", "totalDigits", "whiteSpace"};
|
75
|
+
|
76
|
+
#define FCT_IBOUNDS (1<<FCT_MIN_INCLUSIVE|1<<FCT_MAX_INCLUSIVE)
|
77
|
+
#define FCT_EBOUNDS (1<<FCT_MIN_EXCLUSIVE|1<<FCT_MAX_EXCLUSIVE)
|
78
|
+
#define FCT_BOUNDS (FCT_IBOUNDS|FCT_EBOUNDS)
|
79
|
+
|
80
|
+
#define WS_PRESERVE 0
|
81
|
+
#define WS_REPLACE 1
|
82
|
+
#define WS_COLLAPSE 2
|
83
|
+
|
84
|
+
static int (*match[])(rnv_t *rnv, rx_st_t *rx_st, char *r,char *s,int n)={&rx_match, &rx_rmatch,&rx_cmatch};
|
85
|
+
|
86
|
+
#define TYP_ENTITIES 0
|
87
|
+
#define TYP_ENTITY 1
|
88
|
+
#define TYP_ID 2
|
89
|
+
#define TYP_IDREF 3
|
90
|
+
#define TYP_IDREFS 4
|
91
|
+
#define TYP_NCNAME 5
|
92
|
+
#define TYP_NMTOKEN 6
|
93
|
+
#define TYP_NMTOKENS 7
|
94
|
+
#define TYP_NOTATION 8
|
95
|
+
#define TYP_NAME 9
|
96
|
+
#define TYP_QNAME 10
|
97
|
+
#define TYP_ANY_URI 11
|
98
|
+
#define TYP_BASE64_BINARY 12
|
99
|
+
#define TYP_BOOLEAN 13
|
100
|
+
#define TYP_BYTE 14
|
101
|
+
#define TYP_DATE 15
|
102
|
+
#define TYP_DATE_TIME 16
|
103
|
+
#define TYP_DECIMAL 17
|
104
|
+
#define TYP_DOUBLE 18
|
105
|
+
#define TYP_DURATION 19
|
106
|
+
#define TYP_FLOAT 20
|
107
|
+
#define TYP_G_DAY 21
|
108
|
+
#define TYP_G_MONTH 22
|
109
|
+
#define TYP_G_MONTH_DAY 23
|
110
|
+
#define TYP_G_YEAR 24
|
111
|
+
#define TYP_G_YEAR_MONTH 25
|
112
|
+
#define TYP_HEX_BINARY 26
|
113
|
+
#define TYP_INT 27
|
114
|
+
#define TYP_INTEGER 28
|
115
|
+
#define TYP_LANGUAGE 29
|
116
|
+
#define TYP_LONG 30
|
117
|
+
#define TYP_NEGATIVE_INTEGER 31
|
118
|
+
#define TYP_NON_NEGATIVE_INTEGER 32
|
119
|
+
#define TYP_NON_POSITIVE_INTEGER 33
|
120
|
+
#define TYP_NORMALIZED_STRING 34
|
121
|
+
#define TYP_POSITIVE_INTEGER 35
|
122
|
+
#define TYP_SHORT 36
|
123
|
+
#define TYP_STRING 37
|
124
|
+
#define TYP_TIME 38
|
125
|
+
#define TYP_TOKEN 39
|
126
|
+
#define TYP_UNSIGNED_BYTE 40
|
127
|
+
#define TYP_UNSIGNED_INT 41
|
128
|
+
#define TYP_UNSIGNED_LONG 42
|
129
|
+
#define TYP_UNSIGNED_SHORT 43
|
130
|
+
#define NTYP 44
|
131
|
+
static char *typtab[NTYP]={
|
132
|
+
"ENTITIES", "ENTITY", "ID", "IDREF", "IDREFS", "NCName", "NMTOKEN", "NMTOKENS",
|
133
|
+
"NOTATION", "Name", "QName", "anyURI", "base64Binary", "boolean", "byte", "date",
|
134
|
+
"dateTime", "decimal", "double", "duration", "float", "gDay", "gMonth",
|
135
|
+
"gMonthDay", "gYear", "gYearMonth", "hexBinary", "int", "integer", "language",
|
136
|
+
"long", "negativeInteger", "nonNegativeInteger", "nonPositiveInteger",
|
137
|
+
"normalizedString", "positiveInteger", "short", "string", "time", "token",
|
138
|
+
"unsignedByte", "unsignedInt", "unsignedLong", "unsignedShort"};
|
139
|
+
|
140
|
+
#define ERR_PARAMETER "invalid XML Schema datatype parameter '%s'"
|
141
|
+
#define ERR_DATATYPE "invalid XML Schema datatype name '%s'"
|
142
|
+
#define ERR_VALUE "invalid value '%s' for XML Schema datatype '%s'"
|
143
|
+
|
144
|
+
struct dura {int yr,mo,dy,hr,mi;double se;};
|
145
|
+
static void durainit(struct dura *d) {d->yr=d->mo=d->dy=d->hr=d->mi=0; d->se=0.0;}
|
146
|
+
|
147
|
+
static void s2dura(struct dura *dp,char *s,int n) {
|
148
|
+
char *end=s+n,*np="0";
|
149
|
+
int sign=1,time=0;
|
150
|
+
durainit(dp);
|
151
|
+
while(s!=end) {
|
152
|
+
switch(*s) {
|
153
|
+
case '-': sign=-1; break;
|
154
|
+
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
|
155
|
+
case '8': case '9': case '.': np=s; break;
|
156
|
+
case 'T': time=1; break;
|
157
|
+
case 'Y': dp->yr=sign*atoi(np); break;
|
158
|
+
case 'M': if(time) dp->mi=sign*atoi(np); else dp->mo=sign*atoi(np); break;
|
159
|
+
case 'D': dp->dy=sign*atoi(np); break;
|
160
|
+
case 'H': dp->hr=sign*atoi(np); break;
|
161
|
+
case 'S': dp->se=sign*atof(np); break;
|
162
|
+
}
|
163
|
+
++s;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
static int duracmp(char *s1,char *s2,int n) {
|
168
|
+
struct dura d1,d2;
|
169
|
+
s2dura(&d1,s1,strlen(s1)); s2dura(&d2,s2,n);
|
170
|
+
if(d1.yr!=d2.yr) return d1.yr-d2.yr;
|
171
|
+
if(d1.mo!=d2.mo) return d1.mo-d2.mo;
|
172
|
+
if(d1.dy!=d2.dy) return d1.dy-d2.dy;
|
173
|
+
if(d1.hr!=d2.hr) return d1.hr-d2.hr;
|
174
|
+
if(d1.mi!=d2.mi) return d1.mi-d2.mi;
|
175
|
+
if(d1.se!=d2.se) return d1.se<d2.se?-1:1;
|
176
|
+
return 0;
|
177
|
+
}
|
178
|
+
|
179
|
+
static int dtcmpn(char *s1,char *s2,int n,char *fmt) {
|
180
|
+
struct xsd_tm tm1,tm2;
|
181
|
+
xsd_mktm(&tm1,fmt,s1); xsd_mktmn(&tm2,fmt,s2,n);
|
182
|
+
return xsd_tmcmp(&tm1,&tm2);
|
183
|
+
}
|
184
|
+
|
185
|
+
static int toklenn(char *s,int n) {
|
186
|
+
char *end=s+n;
|
187
|
+
int u,len=0;
|
188
|
+
SKIP_SPACE:
|
189
|
+
for(;;) { if(s==end) return len?len-1:0;
|
190
|
+
s+=u_get(&u,s);
|
191
|
+
if(!xmlc_white_space(u)) break;
|
192
|
+
}
|
193
|
+
++len;
|
194
|
+
for(;;) { if(s==end) return len;
|
195
|
+
++len;
|
196
|
+
s+=u_get(&u,s);
|
197
|
+
if(xmlc_white_space(u)) goto SKIP_SPACE;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
static int tokcntn(char *s,int n) {
|
202
|
+
char *end=s+n;
|
203
|
+
int u,cnt=0;
|
204
|
+
SKIP_SPACE:
|
205
|
+
for(;;) { if(s==end) return cnt;
|
206
|
+
s+=u_get(&u,s);
|
207
|
+
if(!xmlc_white_space(u)) break;
|
208
|
+
}
|
209
|
+
++cnt;
|
210
|
+
for(;;) { if(s==end) return cnt;
|
211
|
+
s+=u_get(&u,s);
|
212
|
+
if(xmlc_white_space(u)) goto SKIP_SPACE;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
static int b64lenn(char *s,int n) {
|
217
|
+
char *end=s+n;
|
218
|
+
int l=0,len;
|
219
|
+
for(;;) { if(end==s) break;
|
220
|
+
--end;
|
221
|
+
if(!xmlc_white_space(*end)&&*end!='=') {++end; break;}
|
222
|
+
}
|
223
|
+
while(s!=end) {if(!xmlc_white_space(*s)) ++l; ++s;}
|
224
|
+
len=l/4*3;
|
225
|
+
switch(l%4) {
|
226
|
+
case 0: break;
|
227
|
+
case 1: len=-1; break;
|
228
|
+
case 2: len+=1; break;
|
229
|
+
case 3: len+=2; break;
|
230
|
+
}
|
231
|
+
return len;
|
232
|
+
}
|
233
|
+
|
234
|
+
static int fdiglenn(char *s,int n) {
|
235
|
+
char *end=s+n; int len=0;
|
236
|
+
for(;;) { if(end==s) break;
|
237
|
+
--end;
|
238
|
+
if(*end!='0'&&!xmlc_white_space(*end)) {++end; break;}
|
239
|
+
}
|
240
|
+
for(;;) { if(s==end) break;
|
241
|
+
if(*(s++)=='.') {
|
242
|
+
while(s++!=end) ++len;
|
243
|
+
break;
|
244
|
+
}
|
245
|
+
}
|
246
|
+
return len;
|
247
|
+
}
|
248
|
+
|
249
|
+
static int diglenn(char *s,int n) {
|
250
|
+
char *end=s+n; int len=0;
|
251
|
+
for(;;) { if(s==end) break;
|
252
|
+
if(!(xmlc_white_space(*s)||*s=='+'||*s=='-'||*s=='0')) break;
|
253
|
+
++s;
|
254
|
+
}
|
255
|
+
for(;;) { if(s==end||*s=='.'||xmlc_white_space(*s)) break;
|
256
|
+
++len; ++s;
|
257
|
+
}
|
258
|
+
if(len==0) len=1;
|
259
|
+
if(*s=='.') len+=fdiglenn(s,end-s);
|
260
|
+
return len;
|
261
|
+
}
|
262
|
+
|
263
|
+
#define NPAT 16
|
264
|
+
|
265
|
+
struct facets {
|
266
|
+
int set;
|
267
|
+
char *pattern[NPAT+1]; int npat;
|
268
|
+
int length, minLength, maxLength, totalDigits, fractionDigits;
|
269
|
+
char *maxExclusive, *maxInclusive, *minExclusive, *minInclusive;
|
270
|
+
int whiteSpace;
|
271
|
+
};
|
272
|
+
|
273
|
+
/* PAT_DECIMAL is unsigned decimal, signed decimal matches PAT_FIXED */
|
274
|
+
#define PAT_ORDINAL "([0-9]+)"
|
275
|
+
#define PAT_FRACTIONAL "(\\.[0-9]+)"
|
276
|
+
#define PAT_DECIMAL "("PAT_ORDINAL"\\.?|"PAT_ORDINAL"?"PAT_FRACTIONAL")"
|
277
|
+
|
278
|
+
#define PAT_POSITIVE "\\+?"PAT_ORDINAL
|
279
|
+
#define PAT_NON_NEGATIVE "\\+?"PAT_ORDINAL
|
280
|
+
#define PAT_NON_POSITIVE "\\-"PAT_ORDINAL"|0+"
|
281
|
+
#define PAT_NEGATIVE "\\-"PAT_ORDINAL
|
282
|
+
#define PAT_INTEGER "([+\\-]?"PAT_ORDINAL")"
|
283
|
+
|
284
|
+
#define PAT_FIXED "([+\\-]?"PAT_DECIMAL")"
|
285
|
+
#define PAT_FLOATING PAT_FIXED"([Ee]"PAT_INTEGER")?|INF|-INF|NaN"
|
286
|
+
|
287
|
+
#define PAT_HEX_BINARY "[0-9a-fA-F]+"
|
288
|
+
|
289
|
+
#define PAT_BASE64 "([A-Za-z0-9+/] ?)"
|
290
|
+
#define PAT_BASE64_2 "([AQgw] ?)"
|
291
|
+
#define PAT_BASE64_1 "([AEIMQUYcgkosw048] ?)"
|
292
|
+
#define PAT_BASE64_BINARY \
|
293
|
+
"("PAT_BASE64"{4})*" \
|
294
|
+
"("PAT_BASE64 PAT_BASE64_2"= ?=" \
|
295
|
+
"|"PAT_BASE64"{2}" PAT_BASE64_1"=)?"
|
296
|
+
|
297
|
+
#define PAT_ANY_URI "(([a-zA-Z][0-9a-zA-Z+\\-\\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?"
|
298
|
+
|
299
|
+
#define PAT_NCNAME "[\\i-[:]][\\c-[:]]*"
|
300
|
+
#define PAT_QNAME "("PAT_NCNAME":)?"PAT_NCNAME
|
301
|
+
#define PAT_NMTOKEN "\\c+"
|
302
|
+
#define PAT_NAME "\\i\\c*"
|
303
|
+
#define PAT_NCNAMES PAT_NCNAME"( "PAT_NCNAME")*"
|
304
|
+
#define PAT_NMTOKENS PAT_NMTOKEN"( "PAT_NMTOKEN")*"
|
305
|
+
#define PAT_NAMES PAT_NAME"( "PAT_NAME")*"
|
306
|
+
|
307
|
+
#define PAT_LANGUAGE "([a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*)"
|
308
|
+
|
309
|
+
#define PAT_DURAY "("PAT_ORDINAL"Y)"
|
310
|
+
#define PAT_DURAM "("PAT_ORDINAL"M)"
|
311
|
+
#define PAT_DURAD "("PAT_ORDINAL"D)"
|
312
|
+
#define PAT_DURADATE \
|
313
|
+
"(" PAT_DURAY PAT_DURAM"?"PAT_DURAD"?" \
|
314
|
+
"|" PAT_DURAY"?"PAT_DURAM PAT_DURAD"?" \
|
315
|
+
"|" PAT_DURAY"?"PAT_DURAM"?"PAT_DURAD ")"
|
316
|
+
#define PAT_DURAH "("PAT_ORDINAL"H)"
|
317
|
+
#define PAT_DURAM "("PAT_ORDINAL"M)"
|
318
|
+
#define PAT_DURAS "("PAT_DECIMAL"S)"
|
319
|
+
#define PAT_DURATIME \
|
320
|
+
"(T(" PAT_DURAH PAT_DURAM"?"PAT_DURAS"?" \
|
321
|
+
"|" PAT_DURAM"?"PAT_DURAM PAT_DURAS"?" \
|
322
|
+
"|" PAT_DURAS"?"PAT_DURAM"?"PAT_DURAS "))"
|
323
|
+
#define PAT_DURATION "-?P("PAT_DURADATE PAT_DURATIME"|"PAT_DURADATE"|"PAT_DURATIME")"
|
324
|
+
|
325
|
+
#define PAT_ZONE "(Z|[+\\-](0[0-9]|1[0-4]):[0-5][0-9])"
|
326
|
+
#define PAT_YEAR0 "[0-9]{4,}"
|
327
|
+
#define PAT_MONTH0 "(0[1-9]|1[0-2])"
|
328
|
+
#define PAT_DAY0 "([0-2][0-9]|3[01])"
|
329
|
+
#define PAT_YEAR "-?"PAT_YEAR0 PAT_ZONE"?"
|
330
|
+
#define PAT_MONTH "--"PAT_MONTH0"--"PAT_ZONE"?"
|
331
|
+
#define PAT_DAY "---"PAT_DAY0 PAT_ZONE"?"
|
332
|
+
#define PAT_YEAR_MONTH "-?"PAT_YEAR0"-"PAT_MONTH0 PAT_ZONE"?"
|
333
|
+
#define PAT_MONTH_DAY "--"PAT_MONTH0"-"PAT_DAY0 PAT_ZONE"?"
|
334
|
+
#define PAT_DATE0 PAT_YEAR0"-"PAT_MONTH0"-"PAT_DAY0
|
335
|
+
#define PAT_TIME0 "([0-1][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)"PAT_FRACTIONAL"?"
|
336
|
+
#define PAT_DATE "-?"PAT_DATE0 PAT_ZONE"?"
|
337
|
+
#define PAT_TIME PAT_TIME0 PAT_ZONE"?"
|
338
|
+
#define PAT_DATE_TIME "-?"PAT_DATE0"T"PAT_TIME0 PAT_ZONE"?"
|
339
|
+
|
340
|
+
static void anchdec(int *plus,int *zero,char **beg,char **dp,char **end,char *s,int n) {
|
341
|
+
char *end0=s+n;
|
342
|
+
*beg=s; *zero=1; *plus=1;
|
343
|
+
for(;;) { if(end0==*beg) break;
|
344
|
+
--end0;
|
345
|
+
if(!xmlc_white_space(*end0)) {++end0; break;}
|
346
|
+
}
|
347
|
+
*end=end0;
|
348
|
+
for(;;) { if(*end==*beg) break;
|
349
|
+
--*end;
|
350
|
+
if(!(**end=='0'||**end=='+'||**end=='-')) {
|
351
|
+
if(**end!='.') *zero=0;
|
352
|
+
++*end;
|
353
|
+
break;
|
354
|
+
}
|
355
|
+
}
|
356
|
+
*dp=*end;
|
357
|
+
for(;;) { if(*beg==*end) break;
|
358
|
+
if(**beg=='-') *plus=0;
|
359
|
+
else if(!(**beg=='0'||**beg=='+'||xmlc_white_space(**beg))) {
|
360
|
+
if(**beg!='.') *zero=0;
|
361
|
+
for(;;) {
|
362
|
+
if(*dp==*beg) {*dp=*end=end0; break;}
|
363
|
+
--*dp;
|
364
|
+
if(**dp=='.') break;
|
365
|
+
}
|
366
|
+
break;
|
367
|
+
}
|
368
|
+
++*beg;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
static int deccmp(char *s1,int n1,char *s2,int n2) {
|
373
|
+
int p1,p2,z1,z2,cmp;
|
374
|
+
char *d1,*e1,*d2,*e2,*c1,*c2;
|
375
|
+
anchdec(&p1,&z1,&s1,&d1,&e1,s1,n1); anchdec(&p2,&z2,&s2,&d2,&e2,s2,n2);
|
376
|
+
if(z1&&z2) return 0;
|
377
|
+
if(p1!=p2) return p1-p2;
|
378
|
+
cmp=0;
|
379
|
+
if(d1-s1!=d2-s2) cmp=d1-s1-(d2-s2);
|
380
|
+
if(cmp!=0) return p1?cmp:-cmp;
|
381
|
+
c1=s1; c2=s2;
|
382
|
+
for(;;) {
|
383
|
+
if(c1==d1) break;
|
384
|
+
if(*c1!=*c2) {cmp=*c1-*c2; break;}
|
385
|
+
++c1; ++c2;
|
386
|
+
}
|
387
|
+
if(cmp!=0) return p1?cmp:-cmp;
|
388
|
+
if(c1!=e1) ++c1; if(c2!=e2) ++c2;
|
389
|
+
for(;;) {
|
390
|
+
if(c1==e1) {cmp=-(c2!=e2); break;}
|
391
|
+
if(c2==e2) {cmp=1; break;}
|
392
|
+
if(*c1!=*c2) {cmp=*c1-*c2; break;}
|
393
|
+
++c1; ++c2;
|
394
|
+
}
|
395
|
+
return p1?cmp:-cmp;
|
396
|
+
}
|
397
|
+
|
398
|
+
static int chkdec(struct facets *fp,char *s,int n) {
|
399
|
+
int ok=1;
|
400
|
+
if(fp->set&(1<<FCT_MIN_EXCLUSIVE)) ok=ok&&deccmp(s,n,fp->minExclusive,strlen(fp->minExclusive))>0;
|
401
|
+
if(fp->set&(1<<FCT_MIN_INCLUSIVE)) ok=ok&&deccmp(s,n,fp->minInclusive,strlen(fp->minInclusive))>=0;
|
402
|
+
if(fp->set&(1<<FCT_MAX_INCLUSIVE)) ok=ok&&deccmp(s,n,fp->maxInclusive,strlen(fp->maxInclusive))<=0;
|
403
|
+
if(fp->set&(1<<FCT_MAX_EXCLUSIVE)) ok=ok&&deccmp(s,n,fp->maxExclusive,strlen(fp->maxExclusive))<0;
|
404
|
+
return ok;
|
405
|
+
}
|
406
|
+
|
407
|
+
static double atodn(char *s,int n) {
|
408
|
+
return s_tokcmpn("-INF",s,n)==0?-HUGE_VAL
|
409
|
+
: s_tokcmpn("INF",s,n)==0?HUGE_VAL
|
410
|
+
: atof(s);
|
411
|
+
}
|
412
|
+
static double atod(char *s) {return atodn(s,strlen(s));}
|
413
|
+
|
414
|
+
static int chkdbl(struct facets *fp,char *s,int n) {
|
415
|
+
int ok=1,nan=s_tokcmpn("NaN",s,n)==0;
|
416
|
+
double d=atodn(s,n);
|
417
|
+
if(fp->set&(1<<FCT_MIN_EXCLUSIVE)) ok=ok&&!nan&&d>atod(fp->minExclusive);
|
418
|
+
if(fp->set&(1<<FCT_MIN_INCLUSIVE)) ok=ok&&!nan&&d>=atod(fp->minInclusive);
|
419
|
+
if(fp->set&(1<<FCT_MAX_INCLUSIVE)) ok=ok&&!nan&&d<=atod(fp->maxInclusive);
|
420
|
+
if(fp->set&(1<<FCT_MAX_EXCLUSIVE)) ok=ok&&!nan&&d<atod(fp->maxExclusive);
|
421
|
+
return ok;
|
422
|
+
}
|
423
|
+
|
424
|
+
static int chktmlim(rx_st_t *rx_st, char *typ,char *fmt,char *val,int cmpmin,int cmpmax,struct xsd_tm *tmp) {
|
425
|
+
struct xsd_tm tmf; int cmp;
|
426
|
+
if(!xsd_allows(rx_st, typ,"",val,strlen(val))) {error_handler(rx_st, XSD_ER_PARVAL); return 0;}
|
427
|
+
xsd_mktm(&tmf,fmt,val);
|
428
|
+
cmp=xsd_tmcmp(tmp,&tmf);
|
429
|
+
return cmpmin<=cmp&&cmp<=cmpmax;
|
430
|
+
}
|
431
|
+
|
432
|
+
static int chktm(rx_st_t *rx_st, char *typ,char *fmt,struct facets *fp,char *s,int n) {
|
433
|
+
int ok=1;
|
434
|
+
struct xsd_tm tms;
|
435
|
+
if(!xsd_allows(rx_st, typ,"",s,n)) return 0;
|
436
|
+
xsd_mktmn(&tms,fmt,s,n);
|
437
|
+
if(fp->set&(1<<FCT_MIN_EXCLUSIVE)) ok=ok&&chktmlim(rx_st, typ,fmt,fp->minExclusive,1,1,&tms);
|
438
|
+
if(fp->set&(1<<FCT_MIN_INCLUSIVE)) ok=ok&&chktmlim(rx_st, typ,fmt,fp->minInclusive,0,1,&tms);
|
439
|
+
if(fp->set&(1<<FCT_MAX_INCLUSIVE)) ok=ok&&chktmlim(rx_st, typ,fmt,fp->maxInclusive,-1,0,&tms);
|
440
|
+
if(fp->set&(1<<FCT_MAX_EXCLUSIVE)) ok=ok&&chktmlim(rx_st, typ,fmt,fp->maxExclusive,-1,-1,&tms);
|
441
|
+
return ok;
|
442
|
+
}
|
443
|
+
|
444
|
+
int xsd_allows(rx_st_t *rx_st, char *typ,char *ps,char *s,int n) {
|
445
|
+
int ok=1,length;
|
446
|
+
int dt=s_tab(typ,typtab,NTYP);
|
447
|
+
struct facets fct; fct.set=0; fct.npat=0;
|
448
|
+
switch(dt) {
|
449
|
+
case TYP_INTEGER:
|
450
|
+
fct.pattern[fct.npat++]=PAT_INTEGER;
|
451
|
+
dt=TYP_DECIMAL;
|
452
|
+
break;
|
453
|
+
case TYP_POSITIVE_INTEGER:
|
454
|
+
fct.pattern[fct.npat++]=PAT_POSITIVE;
|
455
|
+
dt=TYP_DECIMAL; fct.set|=1<<FCT_MIN_INCLUSIVE;
|
456
|
+
fct.minInclusive="1";
|
457
|
+
break;
|
458
|
+
case TYP_NON_NEGATIVE_INTEGER:
|
459
|
+
fct.pattern[fct.npat++]=PAT_NON_NEGATIVE;
|
460
|
+
dt=TYP_DECIMAL; fct.set|=1<<FCT_MIN_INCLUSIVE;
|
461
|
+
fct.minInclusive="0";
|
462
|
+
break;
|
463
|
+
case TYP_NON_POSITIVE_INTEGER:
|
464
|
+
fct.pattern[fct.npat++]=PAT_NON_POSITIVE;
|
465
|
+
dt=TYP_DECIMAL; fct.set|=1<<FCT_MAX_INCLUSIVE;
|
466
|
+
fct.maxInclusive="0";
|
467
|
+
break;
|
468
|
+
case TYP_NEGATIVE_INTEGER:
|
469
|
+
fct.pattern[fct.npat++]=PAT_NEGATIVE;
|
470
|
+
dt=TYP_DECIMAL; fct.set|=1<<FCT_MAX_INCLUSIVE;
|
471
|
+
fct.maxInclusive="-1";
|
472
|
+
break;
|
473
|
+
case TYP_BYTE:
|
474
|
+
fct.pattern[fct.npat++]=PAT_INTEGER;
|
475
|
+
dt=TYP_DECIMAL; fct.set|=FCT_IBOUNDS;
|
476
|
+
fct.minInclusive="-128"; fct.maxInclusive="127";
|
477
|
+
break;
|
478
|
+
case TYP_UNSIGNED_BYTE:
|
479
|
+
fct.pattern[fct.npat++]=PAT_NON_NEGATIVE;
|
480
|
+
dt=TYP_DECIMAL; fct.set|=FCT_IBOUNDS;
|
481
|
+
fct.minInclusive="0"; fct.maxInclusive="255";
|
482
|
+
break;
|
483
|
+
case TYP_SHORT:
|
484
|
+
fct.pattern[fct.npat++]=PAT_INTEGER;
|
485
|
+
dt=TYP_DECIMAL; fct.set|=FCT_IBOUNDS;
|
486
|
+
fct.minInclusive="-32768"; fct.maxInclusive="32767";
|
487
|
+
break;
|
488
|
+
case TYP_UNSIGNED_SHORT:
|
489
|
+
fct.pattern[fct.npat++]=PAT_NON_NEGATIVE;
|
490
|
+
dt=TYP_DECIMAL; fct.set|=FCT_IBOUNDS;
|
491
|
+
fct.minInclusive="0"; fct.maxInclusive="65535";
|
492
|
+
break;
|
493
|
+
case TYP_INT:
|
494
|
+
fct.pattern[fct.npat++]=PAT_INTEGER;
|
495
|
+
dt=TYP_DECIMAL; fct.set|=FCT_IBOUNDS;
|
496
|
+
fct.minInclusive="-2147483648"; fct.maxInclusive="2147483647";
|
497
|
+
break;
|
498
|
+
case TYP_UNSIGNED_INT:
|
499
|
+
fct.pattern[fct.npat++]=PAT_NON_NEGATIVE;
|
500
|
+
dt=TYP_DECIMAL; fct.set|=FCT_IBOUNDS;
|
501
|
+
fct.minInclusive="0"; fct.maxInclusive="4294967295";
|
502
|
+
break;
|
503
|
+
case TYP_LONG:
|
504
|
+
fct.pattern[fct.npat++]=PAT_INTEGER;
|
505
|
+
dt=TYP_DECIMAL; fct.set|=FCT_IBOUNDS;
|
506
|
+
fct.minInclusive="-9223372036854775808"; fct.maxInclusive="9223372036854775807";
|
507
|
+
break;
|
508
|
+
case TYP_UNSIGNED_LONG:
|
509
|
+
fct.pattern[fct.npat++]=PAT_NON_NEGATIVE;
|
510
|
+
dt=TYP_DECIMAL; fct.set|=FCT_IBOUNDS;
|
511
|
+
fct.minInclusive="0"; fct.maxInclusive="18446744073709551615";
|
512
|
+
break;
|
513
|
+
}
|
514
|
+
|
515
|
+
{ int n;
|
516
|
+
while((n=strlen(ps))) {
|
517
|
+
char *key=ps,*val=key+n+1,*end,i;
|
518
|
+
switch(i=s_tab(key,fcttab,NFCT)) {
|
519
|
+
case FCT_LENGTH: fct.length=(int)strtol(val,&end,10); if(!*val||*end) error_handler(rx_st, XSD_ER_PARVAL,key,val); break;
|
520
|
+
case FCT_MAX_LENGTH: fct.maxLength=(int)strtol(val,&end,10); if(!*val||*end) error_handler(rx_st, XSD_ER_PARVAL,key,val); break;
|
521
|
+
case FCT_MIN_LENGTH: fct.minLength=(int)strtol(val,&end,10); if(!*val||*end) error_handler(rx_st, XSD_ER_PARVAL,key,val); break;
|
522
|
+
case FCT_FRACTION_DIGITS: fct.fractionDigits=(int)strtol(val,&end,10); if(!*val||*end) error_handler(rx_st, XSD_ER_PARVAL,key,val); break;
|
523
|
+
case FCT_TOTAL_DIGITS: fct.totalDigits=(int)strtol(val,&end,10); if(!*val||*end) error_handler(rx_st, XSD_ER_PARVAL,key,val); break;
|
524
|
+
case FCT_PATTERN:
|
525
|
+
if(fct.npat==NPAT) error_handler(rx_st, XSD_ER_NPAT); else {
|
526
|
+
fct.pattern[fct.npat++]=val;
|
527
|
+
} break;
|
528
|
+
case FCT_MAX_EXCLUSIVE: fct.maxExclusive=val; break;
|
529
|
+
case FCT_MAX_INCLUSIVE: fct.maxInclusive=val; break;
|
530
|
+
case FCT_MIN_EXCLUSIVE: fct.minExclusive=val; break;
|
531
|
+
case FCT_MIN_INCLUSIVE: fct.minInclusive=val; break;
|
532
|
+
case FCT_WHITE_SPACE: error_handler(rx_st, XSD_ER_WS); break;
|
533
|
+
case FCT_ENUMERATION: error_handler(rx_st, XSD_ER_ENUM); break;
|
534
|
+
case NFCT: error_handler(rx_st, XSD_ER_PAR,key); break;
|
535
|
+
default: assert(0);
|
536
|
+
}
|
537
|
+
fct.set|=1<<i;
|
538
|
+
ps=val+strlen(val)+1;
|
539
|
+
}
|
540
|
+
}
|
541
|
+
|
542
|
+
fct.whiteSpace=WS_COLLAPSE;
|
543
|
+
length=INT_MAX;
|
544
|
+
switch(dt) {
|
545
|
+
/*primitive*/
|
546
|
+
case TYP_STRING: fct.whiteSpace=WS_PRESERVE;
|
547
|
+
length=u_strnlen(s,n);
|
548
|
+
break;
|
549
|
+
case TYP_BOOLEAN:
|
550
|
+
fct.pattern[fct.npat++]="true|false|1|0";
|
551
|
+
break;
|
552
|
+
case TYP_DECIMAL:
|
553
|
+
fct.pattern[fct.npat++]=PAT_FIXED;
|
554
|
+
if(fct.set&(1<<FCT_FRACTION_DIGITS)) ok=ok&&fdiglenn(s,n)<=fct.fractionDigits;
|
555
|
+
if(fct.set&(1<<FCT_TOTAL_DIGITS)) ok=ok&&diglenn(s,n)<=fct.totalDigits;
|
556
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chkdec(&fct,s,n);
|
557
|
+
break;
|
558
|
+
case TYP_FLOAT: case TYP_DOUBLE: /* float and double is the same type */
|
559
|
+
fct.pattern[fct.npat++]=PAT_FLOATING;
|
560
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chkdbl(&fct,s,n);
|
561
|
+
break;
|
562
|
+
case TYP_DURATION:
|
563
|
+
fct.pattern[fct.npat++]=PAT_DURATION;
|
564
|
+
break;
|
565
|
+
case TYP_DATE_TIME:
|
566
|
+
fct.pattern[fct.npat++]=PAT_DATE_TIME;
|
567
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chktm(rx_st, typ,"ymdtz",&fct,s,n);
|
568
|
+
break;
|
569
|
+
case TYP_DATE:
|
570
|
+
fct.pattern[fct.npat++]=PAT_DATE;
|
571
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chktm(rx_st, typ,"ymdz",&fct,s,n);
|
572
|
+
break;
|
573
|
+
case TYP_TIME:
|
574
|
+
fct.pattern[fct.npat++]=PAT_TIME;
|
575
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chktm(rx_st, typ,"tz",&fct,s,n);
|
576
|
+
break;
|
577
|
+
case TYP_G_YEAR_MONTH:
|
578
|
+
fct.pattern[fct.npat++]=PAT_YEAR_MONTH;
|
579
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chktm(rx_st, typ,"ymz",&fct,s,n);
|
580
|
+
break;
|
581
|
+
case TYP_G_YEAR:
|
582
|
+
fct.pattern[fct.npat++]=PAT_YEAR;
|
583
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chktm(rx_st, typ,"yz",&fct,s,n);
|
584
|
+
break;
|
585
|
+
case TYP_G_MONTH_DAY:
|
586
|
+
fct.pattern[fct.npat++]=PAT_MONTH_DAY;
|
587
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chktm(rx_st, typ,"mdz",&fct,s,n);
|
588
|
+
break;
|
589
|
+
case TYP_G_DAY:
|
590
|
+
fct.pattern[fct.npat++]=PAT_DAY;
|
591
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chktm(rx_st, typ,"dz",&fct,s,n);
|
592
|
+
break;
|
593
|
+
case TYP_G_MONTH:
|
594
|
+
fct.pattern[fct.npat++]=PAT_MONTH;
|
595
|
+
if(fct.set&FCT_BOUNDS) ok=ok&chktm(rx_st, typ,"mz",&fct,s,n);
|
596
|
+
break;
|
597
|
+
case TYP_HEX_BINARY:
|
598
|
+
fct.pattern[fct.npat++]=PAT_HEX_BINARY;
|
599
|
+
length=(toklenn(s,n)+1)/2;
|
600
|
+
break;
|
601
|
+
case TYP_BASE64_BINARY:
|
602
|
+
fct.pattern[fct.npat++]=PAT_BASE64_BINARY;
|
603
|
+
length=b64lenn(s,n);
|
604
|
+
break;
|
605
|
+
case TYP_ANY_URI:
|
606
|
+
fct.pattern[fct.npat++]=PAT_ANY_URI;
|
607
|
+
length=toklenn(s,n);
|
608
|
+
break;
|
609
|
+
case TYP_QNAME: case TYP_NOTATION:
|
610
|
+
fct.pattern[fct.npat++]=PAT_QNAME;
|
611
|
+
fct.set&=~(1<<FCT_LENGTH|1<<FCT_MIN_LENGTH|1<<FCT_MAX_LENGTH); /* the errata states that any value is valid */
|
612
|
+
break;
|
613
|
+
/*derived*/
|
614
|
+
case TYP_NORMALIZED_STRING: fct.whiteSpace=WS_REPLACE;
|
615
|
+
length=u_strnlen(s,n);
|
616
|
+
break;
|
617
|
+
case TYP_TOKEN:
|
618
|
+
length=toklenn(s,n);
|
619
|
+
break;
|
620
|
+
case TYP_LANGUAGE:
|
621
|
+
fct.pattern[fct.npat++]=PAT_LANGUAGE;
|
622
|
+
length=toklenn(s,n);
|
623
|
+
break;
|
624
|
+
case TYP_NMTOKEN:
|
625
|
+
fct.pattern[fct.npat++]=PAT_NMTOKEN;
|
626
|
+
length=toklenn(s,n);
|
627
|
+
break;
|
628
|
+
case TYP_NMTOKENS:
|
629
|
+
fct.pattern[fct.npat++]=PAT_NMTOKENS;
|
630
|
+
length=tokcntn(s,n);
|
631
|
+
break;
|
632
|
+
case TYP_NAME:
|
633
|
+
fct.pattern[fct.npat++]=PAT_NAME;
|
634
|
+
length=toklenn(s,n);
|
635
|
+
break;
|
636
|
+
case TYP_NCNAME:
|
637
|
+
fct.pattern[fct.npat++]=PAT_NCNAME;
|
638
|
+
length=toklenn(s,n);
|
639
|
+
break;
|
640
|
+
case TYP_ID:
|
641
|
+
fct.pattern[fct.npat++]=PAT_NCNAME;
|
642
|
+
length=toklenn(s,n);
|
643
|
+
break;
|
644
|
+
case TYP_IDREF:
|
645
|
+
fct.pattern[fct.npat++]=PAT_NCNAME;
|
646
|
+
length=toklenn(s,n);
|
647
|
+
break;
|
648
|
+
case TYP_IDREFS:
|
649
|
+
fct.pattern[fct.npat++]=PAT_NCNAMES;
|
650
|
+
length=tokcntn(s,n);
|
651
|
+
break;
|
652
|
+
case TYP_ENTITY:
|
653
|
+
fct.pattern[fct.npat++]=PAT_NCNAME;
|
654
|
+
length=toklenn(s,n);
|
655
|
+
break;
|
656
|
+
case TYP_ENTITIES:
|
657
|
+
fct.pattern[fct.npat++]=PAT_NCNAMES;
|
658
|
+
length=tokcntn(s,n);
|
659
|
+
break;
|
660
|
+
case NTYP: error_handler(rx_st, XSD_ER_TYP,typ); break;
|
661
|
+
default: assert(0);
|
662
|
+
}
|
663
|
+
|
664
|
+
while(fct.npat--) ok=ok&&match[fct.whiteSpace](rx_st->rnv, rx_st, fct.pattern[fct.npat],s,n);
|
665
|
+
|
666
|
+
if(fct.set&(1<<FCT_LENGTH)) ok=ok&&length==fct.length;
|
667
|
+
if(fct.set&(1<<FCT_MAX_LENGTH)) ok=ok&&length<=fct.maxLength;
|
668
|
+
if(fct.set&(1<<FCT_MIN_LENGTH)) ok=ok&&length>=fct.minLength;
|
669
|
+
|
670
|
+
return ok;
|
671
|
+
}
|
672
|
+
|
673
|
+
static int dblcmpn(char *val,char *s,char n) {
|
674
|
+
double d1,d2;
|
675
|
+
return s_tokcmpn(val,s,n)==0?0
|
676
|
+
: s_tokcmpn(val,"NaN",3)==0||s_tokcmpn("NaN",s,n)==0?1
|
677
|
+
: (d1=atod(val),d2=atodn(s,n),d1<d2?-1:d1>d2?1:0);
|
678
|
+
}
|
679
|
+
|
680
|
+
static int hexcmpn(char *s1,char *s2,int n) {
|
681
|
+
char *end=s2+n;
|
682
|
+
for(;;++s1,++s2) {
|
683
|
+
while(*s1&&xmlc_white_space(*s1)) ++s1;
|
684
|
+
while(s2!=end&&xmlc_white_space(*s2)) ++s2;
|
685
|
+
if(s2==end) return *s1;
|
686
|
+
if(!*s1) return -*s2;
|
687
|
+
switch(*s1) {
|
688
|
+
case 'a': case 'A': if(*s2=='a'||*s2=='A') continue;
|
689
|
+
case 'b': case 'B': if(*s2=='b'||*s2=='B') continue;
|
690
|
+
case 'c': case 'C': if(*s2=='c'||*s2=='C') continue;
|
691
|
+
case 'd': case 'D': if(*s2=='d'||*s2=='D') continue;
|
692
|
+
case 'e': case 'E': if(*s2=='e'||*s2=='E') continue;
|
693
|
+
case 'f': case 'F': if(*s2=='f'||*s2=='F') continue;
|
694
|
+
default: if(*s1!=*s2) return *s1-*s2;
|
695
|
+
}
|
696
|
+
}
|
697
|
+
}
|
698
|
+
|
699
|
+
static int b64cmpn(char *s1,char *s2,int n) {
|
700
|
+
char *end=s2+n;
|
701
|
+
for(;;++s1,++s2) {
|
702
|
+
while(*s1&&xmlc_white_space(*s1)) ++s1;
|
703
|
+
while(s2!=end&&xmlc_white_space(*s2)) ++s2;
|
704
|
+
if(s2==end) return *s1;
|
705
|
+
if(!*s1) return -*s2;
|
706
|
+
if(*s1!=*s2) return *s1-*s2;
|
707
|
+
}
|
708
|
+
}
|
709
|
+
|
710
|
+
static int nrmcmpn(char *s1,char *s2,int n) {
|
711
|
+
char *end=s2+n;
|
712
|
+
for(;;++s1,++s2) {
|
713
|
+
if(s2==end) return *s1;
|
714
|
+
if(!*s1) return -*s2;
|
715
|
+
if(!(*s1==*s2||(xmlc_white_space(*s1)&&xmlc_white_space(*s2))))
|
716
|
+
return *s1-*s2;
|
717
|
+
}
|
718
|
+
}
|
719
|
+
|
720
|
+
static int qncmpn(char *s1,char *s2,int n2) { /* context is not passed over; compare local parts */
|
721
|
+
char *ln1=s1,*ln2=s2;
|
722
|
+
int n=n2;
|
723
|
+
while(*ln1&&*ln1!=':') ++ln1;
|
724
|
+
while(n!=0&&*ln2!=':') {++ln2; --n;}
|
725
|
+
if(*ln1) {
|
726
|
+
return n?s_tokcmpn(ln1+1,ln2+1,n-1):s_tokcmpn(ln1+1,s2,n2);
|
727
|
+
} else {
|
728
|
+
return n?s_tokcmpn(s1,ln2+1,n-1):s_tokcmpn(s1,s2,n2);
|
729
|
+
}
|
730
|
+
}
|
731
|
+
|
732
|
+
int xsd_equal(rx_st_t *rx_st, char *typ,char *val,char *s,int n) {
|
733
|
+
if(!xsd_allows(rx_st, typ,"",val,strlen(val))) {
|
734
|
+
error_handler(rx_st, XSD_ER_VAL,val);
|
735
|
+
return 0;
|
736
|
+
}
|
737
|
+
if(!xsd_allows(rx_st, typ,"",s,n)) return 0;
|
738
|
+
switch(s_tab(typ,typtab,NTYP)) {
|
739
|
+
/*primitive*/
|
740
|
+
case TYP_STRING: return s_cmpn(val,s,n)==0;
|
741
|
+
case TYP_BOOLEAN: return (s_tokcmpn("true",val,strlen(val))==0||s_tokcmpn("1",val,strlen(val))==0)==(s_tokcmpn("true",s,n)==0||s_tokcmpn("1",s,n)==0);
|
742
|
+
case TYP_DECIMAL: return deccmp(val,strlen(val),s,n)==0;
|
743
|
+
case TYP_FLOAT: case TYP_DOUBLE: return dblcmpn(val,s,n)==0;
|
744
|
+
case TYP_DURATION: return duracmp(val,s,n)==0;
|
745
|
+
case TYP_DATE_TIME: return dtcmpn(val,s,n,"ymdtz")==0;
|
746
|
+
case TYP_DATE: return dtcmpn(val,s,n,"ymdz")==0;
|
747
|
+
case TYP_TIME: return dtcmpn(val,s,n,"tz")==0;
|
748
|
+
case TYP_G_YEAR_MONTH: return dtcmpn(val,s,n,"ymz")==0;
|
749
|
+
case TYP_G_YEAR: return dtcmpn(val,s,n,"yz")==0;
|
750
|
+
case TYP_G_MONTH_DAY: return dtcmpn(val,s,n,"mdz")==0;
|
751
|
+
case TYP_G_DAY: return dtcmpn(val,s,n,"dz")==0;
|
752
|
+
case TYP_G_MONTH: return dtcmpn(val,s,n,"mz")==0;
|
753
|
+
case TYP_HEX_BINARY: return hexcmpn(val,s,n)==0;
|
754
|
+
case TYP_BASE64_BINARY: return b64cmpn(val,s,n)==0;
|
755
|
+
case TYP_ANY_URI: return s_tokcmpn(val,s,n)==0;
|
756
|
+
case TYP_QNAME: case TYP_NOTATION:
|
757
|
+
return qncmpn(val,s,n)==0;
|
758
|
+
/*derived*/
|
759
|
+
case TYP_NORMALIZED_STRING: return nrmcmpn(val,s,n)==0;
|
760
|
+
case TYP_TOKEN:
|
761
|
+
case TYP_LANGUAGE:
|
762
|
+
case TYP_NMTOKEN:
|
763
|
+
case TYP_NMTOKENS:
|
764
|
+
case TYP_NAME:
|
765
|
+
case TYP_NCNAME:
|
766
|
+
case TYP_ID:
|
767
|
+
case TYP_IDREF:
|
768
|
+
case TYP_IDREFS:
|
769
|
+
case TYP_ENTITY:
|
770
|
+
case TYP_ENTITIES: return s_tokcmpn(val,s,n)==0;
|
771
|
+
case TYP_INTEGER:
|
772
|
+
case TYP_POSITIVE_INTEGER:
|
773
|
+
case TYP_NON_NEGATIVE_INTEGER:
|
774
|
+
case TYP_NON_POSITIVE_INTEGER:
|
775
|
+
case TYP_NEGATIVE_INTEGER:
|
776
|
+
case TYP_BYTE:
|
777
|
+
case TYP_UNSIGNED_BYTE:
|
778
|
+
case TYP_SHORT:
|
779
|
+
case TYP_UNSIGNED_SHORT:
|
780
|
+
case TYP_INT:
|
781
|
+
case TYP_UNSIGNED_INT:
|
782
|
+
case TYP_LONG:
|
783
|
+
case TYP_UNSIGNED_LONG: return deccmp(val,strlen(val),s,n)==0;
|
784
|
+
case NTYP: error_handler(rx_st, XSD_ER_TYP,typ); return 0;
|
785
|
+
default: assert(0);
|
786
|
+
}
|
787
|
+
return 0;
|
788
|
+
}
|
789
|
+
|