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.
- 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
|
+
|