ruby_rnv 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/ext/rnv/extconf.rb +15 -0
  4. data/ext/rnv/ruby_rnv.c +742 -0
  5. data/ext/rnv/src/ary.c +78 -0
  6. data/ext/rnv/src/ary.h +10 -0
  7. data/ext/rnv/src/drv.c +472 -0
  8. data/ext/rnv/src/drv.h +35 -0
  9. data/ext/rnv/src/er.c +15 -0
  10. data/ext/rnv/src/er.h +16 -0
  11. data/ext/rnv/src/erbit.h +14 -0
  12. data/ext/rnv/src/ht.c +90 -0
  13. data/ext/rnv/src/ht.h +22 -0
  14. data/ext/rnv/src/ll.h +43 -0
  15. data/ext/rnv/src/m.c +60 -0
  16. data/ext/rnv/src/m.h +10 -0
  17. data/ext/rnv/src/rn.c +569 -0
  18. data/ext/rnv/src/rn.h +150 -0
  19. data/ext/rnv/src/rnc.c +1191 -0
  20. data/ext/rnv/src/rnc.h +68 -0
  21. data/ext/rnv/src/rnd.c +436 -0
  22. data/ext/rnv/src/rnd.h +25 -0
  23. data/ext/rnv/src/rnl.c +62 -0
  24. data/ext/rnv/src/rnl.h +18 -0
  25. data/ext/rnv/src/rnv.c +158 -0
  26. data/ext/rnv/src/rnv.h +30 -0
  27. data/ext/rnv/src/rnx.c +153 -0
  28. data/ext/rnv/src/rnx.h +16 -0
  29. data/ext/rnv/src/rx.c +749 -0
  30. data/ext/rnv/src/rx.h +43 -0
  31. data/ext/rnv/src/rx_cls_ranges.c +126 -0
  32. data/ext/rnv/src/rx_cls_u.c +262 -0
  33. data/ext/rnv/src/s.c +103 -0
  34. data/ext/rnv/src/s.h +32 -0
  35. data/ext/rnv/src/sc.c +62 -0
  36. data/ext/rnv/src/sc.h +26 -0
  37. data/ext/rnv/src/type.h +121 -0
  38. data/ext/rnv/src/u.c +88 -0
  39. data/ext/rnv/src/u.h +26 -0
  40. data/ext/rnv/src/xcl.c +472 -0
  41. data/ext/rnv/src/xmlc.c +20 -0
  42. data/ext/rnv/src/xmlc.h +16 -0
  43. data/ext/rnv/src/xsd.c +789 -0
  44. data/ext/rnv/src/xsd.h +27 -0
  45. data/ext/rnv/src/xsd_tm.c +100 -0
  46. data/ext/rnv/src/xsd_tm.h +15 -0
  47. data/lib/rnv.rb +2 -0
  48. data/lib/rnv/ox_sax_document.rb +84 -0
  49. data/lib/rnv/validator.rb +104 -0
  50. metadata +175 -0
@@ -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);}
@@ -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
+