xmlschemastypes.c revision dda8f1ba9fb2e731e2dd6aa325ed07add7905ec3
14255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* 24255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * schemastypes.c : implementation of the XML Schema Datatypes 34255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * definition and validity checking 44255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 54255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * See Copyright for the status of this software. 64255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 74255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Daniel Veillard <veillard@redhat.com> 84255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 94255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define IN_LIBXML 114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include "libxml.h" 124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#ifdef LIBXML_SCHEMAS_ENABLED 144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <string.h> 164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlmemory.h> 174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/parser.h> 184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/parserInternals.h> 194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/hash.h> 204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/valid.h> 214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlschemas.h> 234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/schemasInternals.h> 244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#include <libxml/xmlschemastypes.h> 254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 26070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#ifdef HAVE_MATH_H 27070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#include <math.h> 28070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#endif 29070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define DEBUG 314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define TODO \ 334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlGenericError(xmlGenericErrorContext, \ 344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard "Unimplemented block at %s:%d\n", \ 354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard __FILE__, __LINE__); 364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#define XML_SCHEMAS_NAMESPACE_NAME \ 384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard (const xmlChar *)"http://www.w3.org/2001/XMLSchema" 394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef enum { 414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_SCHEMAS_UNKNOWN = 0, 424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_SCHEMAS_STRING, 434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_SCHEMAS_NMTOKEN, 444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_SCHEMAS_DECIMAL, 45070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_TIME, 46070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_GDAY, 47070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_GMONTH, 48070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_GMONTHDAY, 49070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_GYEAR, 50070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_GYEARMONTH, 51070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_DATE, 52070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_DATETIME, 53070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard XML_SCHEMAS_DURATION, 5484d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard XML_SCHEMAS_FLOAT, 5584d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard XML_SCHEMAS_DOUBLE, 564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_SCHEMAS_, 574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_SCHEMAS_XXX 584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} xmlSchemaValType; 594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardunsigned long powten[10] = { 614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000L, 624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 100000000L, 1000000000L 634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 65070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Date value */ 66070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardtypedef struct _xmlSchemaValDate xmlSchemaValDate; 67070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardtypedef xmlSchemaValDate *xmlSchemaValDatePtr; 68070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstruct _xmlSchemaValDate { 69070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard long year; 70070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard unsigned int mon :4; /* 1 <= mon <= 12 */ 71070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard unsigned int day :5; /* 1 <= day <= 31 */ 72070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard unsigned int hour :5; /* 0 <= hour <= 23 */ 73070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard unsigned int min :6; /* 0 <= min <= 59 */ 74070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard double sec; 75070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int tz_flag :1; /* is tzo explicitely set? */ 76070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int tzo :11; /* -1440 <= tzo <= 1440 */ 77070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}; 78070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 79070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* Duration value */ 80070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardtypedef struct _xmlSchemaValDuration xmlSchemaValDuration; 81070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardtypedef xmlSchemaValDuration *xmlSchemaValDurationPtr; 82070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstruct _xmlSchemaValDuration { 83070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard long mon; /* mon stores years also */ 84070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard long day; 85070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard double sec; /* sec stores min and hour also */ 86070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard}; 87070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef struct _xmlSchemaValDecimal xmlSchemaValDecimal; 894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardtypedef xmlSchemaValDecimal *xmlSchemaValDecimalPtr; 904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlSchemaValDecimal { 914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard /* would use long long but not portable */ 924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard unsigned long base; 934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard unsigned int extra; 945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard unsigned int sign:1; 954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int frac:7; 964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int total:8; 974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstruct _xmlSchemaVal { 1004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaValType type; 1014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard union { 1025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlSchemaValDecimal decimal; 103070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaValDate date; 104070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaValDuration dur; 10584d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard float f; 10684d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard double d; 1074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } value; 1084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard}; 1094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int xmlSchemaTypesInitialized = 0; 1114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlHashTablePtr xmlSchemaTypesBank = NULL; 1124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeStringDef = NULL; 1144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeAnyTypeDef = NULL; 1154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeAnySimpleTypeDef = NULL; 1164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeDecimalDef = NULL; 117070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeDatetimeDef = NULL; 1184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeDateDef = NULL; 119070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeTimeDef = NULL; 120070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeGYearDef = NULL; 121070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeGYearMonthDef = NULL; 122070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeGDayDef = NULL; 123070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeGMonthDayDef = NULL; 124070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeGMonthDef = NULL; 125070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeDurationDef = NULL; 1264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypePositiveIntegerDef = NULL; 1274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeNonNegativeIntegerDef = NULL; 1284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeNmtoken = NULL; 12984d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeFloatDef = NULL; 13084d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillardstatic xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL; 1314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* 1334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaInitBasicType: 1344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @name: the type name 1354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 1364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Initialize one default type 1374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaTypePtr 1394255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaInitBasicType(const char *name) { 1404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypePtr ret; 1414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); 1434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == NULL) { 1444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlGenericError(xmlGenericErrorContext, 1454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard "Could not initilize type %s: out of memory\n", name); 1464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 1474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 1484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(ret, 0, sizeof(xmlSchemaType)); 1494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->name = xmlStrdup((const xmlChar *)name); 1504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->type = XML_SCHEMA_TYPE_BASIC; 1514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret->contentType = XML_SCHEMA_CONTENT_BASIC; 1524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlHashAddEntry2(xmlSchemaTypesBank, ret->name, 1534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard XML_SCHEMAS_NAMESPACE_NAME, ret); 1544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 1554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 1564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/* 1584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaInitTypes: 1594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 1604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Initialize the default XML Schemas type library 1614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 1634255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaInitTypes(void) { 1644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (xmlSchemaTypesInitialized != 0) 1654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 1664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypesBank = xmlHashCreate(40); 1674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypeStringDef = xmlSchemaInitBasicType("string"); 1694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType("anyType"); 1704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType("anySimpleType"); 1714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType("decimal"); 1724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypeDateDef = xmlSchemaInitBasicType("date"); 173070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType("dateTime"); 174070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaTypeTimeDef = xmlSchemaInitBasicType("time"); 175070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaTypeGYearDef = xmlSchemaInitBasicType("gYear"); 176070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType("gYearMonth"); 177070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType("gMonth"); 178070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType("gMonthDay"); 179070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaTypeGDayDef = xmlSchemaInitBasicType("gDay"); 180070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaTypeDurationDef = xmlSchemaInitBasicType("duration"); 1814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypePositiveIntegerDef = xmlSchemaInitBasicType("positiveInteger"); 1824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypeNonNegativeIntegerDef = 1834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaInitBasicType("nonNegativeInteger"); 1844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypeNmtoken = xmlSchemaInitBasicType("NMTOKEN"); 18584d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard xmlSchemaTypeFloatDef = xmlSchemaInitBasicType("float"); 18684d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType("double"); 1874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypesInitialized = 1; 1894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 1904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 1914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 1924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaCleanupTypes: 1934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 1944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Cleanup the default XML Schemas type library 1954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1964255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 1974255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaCleanupTypes(void) { 1984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (xmlSchemaTypesInitialized == 0) 1994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 2004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlHashFree(xmlSchemaTypesBank, (xmlHashDeallocator) xmlSchemaFreeType); 2014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaTypesInitialized = 0; 2024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 2034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 2054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaNewValue: 2064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type: the value type 2074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 2084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Allocate a new simple type value 2094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 2104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns a pointer to the new value or NULL in case of error 2114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 2124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic xmlSchemaValPtr 2134255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaNewValue(xmlSchemaValType type) { 2144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaValPtr value; 2154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value = (xmlSchemaValPtr) xmlMalloc(sizeof(xmlSchemaVal)); 2174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (value == NULL) { 2184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 2194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 2204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard memset(value, 0, sizeof(xmlSchemaVal)); 2214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard value->type = type; 2224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(value); 2234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 2244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 2264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaFreeValue: 2274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @value: the value to free 2284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 2294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Cleanup the default XML Schemas type library 2304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 2314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardvoid 2324255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaFreeValue(xmlSchemaValPtr value) { 2334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (value == NULL) 2344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return; 2354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlFree(value); 2364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 2374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 2384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 2394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaGetPredefinedType: 2404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @name: the type name 2414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @ns: the URI of the namespace usually "http://www.w3.org/2001/XMLSchema" 2424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 2434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Lookup a type in the default XML Schemas type library 2444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 2454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns the type if found, NULL otherwise 2464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 2474255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaTypePtr 2484255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaGetPredefinedType(const xmlChar *name, const xmlChar *ns) { 2494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (xmlSchemaTypesInitialized == 0) 2504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaInitTypes(); 2514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (name == NULL) 2524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(NULL); 2534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return((xmlSchemaTypePtr) xmlHashLookup2(xmlSchemaTypesBank, name, ns)); 2544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 255070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 256070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/**************************************************************** 257070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * * 258070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Convenience macros and functions * 259070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * * 260070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ****************************************************************/ 261070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 262070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define IS_TZO_CHAR(c) \ 263070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ((c == 0) || (c == 'Z') || (c == '+') || (c == '-')) 264070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 265070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_YEAR(yr) (yr != 0) 266070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_MONTH(mon) ((mon >= 1) && (mon <= 12)) 267070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/* VALID_DAY should only be used when month is unknown */ 268070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_DAY(day) ((day >= 1) && (day <= 31)) 269070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_HOUR(hr) ((hr >= 0) && (hr <= 23)) 270070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_MIN(min) ((min >= 0) && (min <= 59)) 271070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_SEC(sec) ((sec >= 0) && (sec < 60)) 272070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_TZO(tzo) ((tzo > -1440) && (tzo < 1440)) 273070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define IS_LEAP(y) \ 274070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0)) 275070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 276070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic const long daysInMonth[12] = 277070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 278070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic const long daysInMonthLeap[12] = 279070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 280070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 2815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define MAX_DAYINMONTH(yr,mon) \ 2825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (IS_LEAP(yr) ? daysInMonthLeap[mon - 1] : daysInMonth[mon - 1]) 2835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 284070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_MDAY(dt) \ 285070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (IS_LEAP(dt->year) ? \ 286070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (dt->day <= daysInMonthLeap[dt->mon - 1]) : \ 287070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (dt->day <= daysInMonth[dt->mon - 1])) 288070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 289070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_DATE(dt) \ 290070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt)) 291070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 292070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_TIME(dt) \ 293070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (VALID_HOUR(dt->hour) && VALID_MIN(dt->min) && \ 294070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard VALID_SEC(dt->sec) && VALID_TZO(dt->tzo)) 295070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 296070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define VALID_DATETIME(dt) \ 297070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (VALID_DATE(dt) && VALID_TIME(dt)) 298070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 299070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define SECS_PER_MIN (60) 300070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define SECS_PER_HOUR (60 * SECS_PER_MIN) 301070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define SECS_PER_DAY (24 * SECS_PER_HOUR) 302070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 3035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic const long dayInYearByMonth[12] = 3045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; 3055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic const long dayInLeapYearByMonth[12] = 3065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; 3075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 3085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define DAY_IN_YEAR(day, month, year) \ 3095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ((IS_LEAP(year) ? \ 3105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard dayInLeapYearByMonth[month - 1] : \ 3115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard dayInYearByMonth[month - 1]) + day) 3125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 3135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#ifdef DEBUG 3145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define DEBUG_DATE(dt) \ 3155a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlGenericError(xmlGenericErrorContext, \ 3165a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard "type=%o %04ld-%02u-%02uT%02u:%02u:%03f", \ 3175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard dt->type,dt->value.date.year,dt->value.date.mon, \ 3185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard dt->value.date.day,dt->value.date.hour,dt->value.date.min, \ 3195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard dt->value.date.sec); \ 3205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (dt->value.date.tz_flag) \ 3215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (dt->value.date.tzo != 0) \ 3225a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlGenericError(xmlGenericErrorContext, \ 3235a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard "%+05d\n",dt->value.date.tzo); \ 3245a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else \ 3255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlGenericError(xmlGenericErrorContext, "Z\n"); \ 3265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else \ 3275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlGenericError(xmlGenericErrorContext,"\n") 3285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#else 3295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define DEBUG_DATE(dt) 3305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#endif 3315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 332070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 333070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * _xmlSchemaParseGYear: 334070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @dt: pointer to a date structure 335070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @str: pointer to the string to analyze 336070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 337070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a xs:gYear without time zone and fills in the appropriate 338070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * field of the @dt structure. @str is updated to point just after the 339070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * xs:gYear. It is supposed that @dt->year is big enough to contain 340070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * the year. 341070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 342070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Returns 0 or the error code 343070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 344070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int 345070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard_xmlSchemaParseGYear (xmlSchemaValDatePtr dt, const xmlChar **str) { 346070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const xmlChar *cur = *str, *firstChar; 347070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int isneg = 0, digcnt = 0; 348070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 349070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (((*cur < '0') || (*cur > '9')) && 350070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (*cur != '-') && (*cur != '+')) 351070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 352070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 353070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur == '-') { 354070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard isneg = 1; 355070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 356070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 357070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 358070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard firstChar = cur; 359070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 360070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 361070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->year = dt->year * 10 + (*cur - '0'); 362070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 363070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard digcnt++; 364070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 365070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 366070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* year must be at least 4 digits (CCYY); over 4 367070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * digits cannot have a leading zero. */ 368070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((digcnt < 4) || ((digcnt > 4) && (*firstChar == '0'))) 369070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 370070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 371070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (isneg) 372070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->year = - dt->year; 373070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 374070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!VALID_YEAR(dt->year)) 375070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 2; 376070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 377070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard *str = cur; 378070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 379070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard} 380070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 381070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 382070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * PARSE_2_DIGITS: 383070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @num: the integer to fill in 384070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @cur: an #xmlChar * 385070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @invalid: an integer 386070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 387070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a 2-digits integer and updates @num with the value. @cur is 388070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * updated to point just after the integer. 389070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * In case of error, @invalid is set to %TRUE, values of @num and 390070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @cur are undefined. 391070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 392070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define PARSE_2_DIGITS(num, cur, invalid) \ 393070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((cur[0] < '0') || (cur[0] > '9') || \ 394070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (cur[1] < '0') || (cur[1] > '9')) \ 395070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard invalid = 1; \ 396070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else \ 397070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard num = (cur[0] - '0') * 10 + (cur[1] - '0'); \ 398070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur += 2; 399070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 400070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 401070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * PARSE_FLOAT: 402070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @num: the double to fill in 403070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @cur: an #xmlChar * 404070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @invalid: an integer 405070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 406070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a float and updates @num with the value. @cur is 407070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * updated to point just after the float. The float must have a 408070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 2-digits integer part and may or may not have a decimal part. 409070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * In case of error, @invalid is set to %TRUE, values of @num and 410070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @cur are undefined. 411070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 412070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define PARSE_FLOAT(num, cur, invalid) \ 413070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_2_DIGITS(num, cur, invalid); \ 414070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!invalid && (*cur == '.')) { \ 415070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard double mult = 1; \ 416070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; \ 417070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((*cur < '0') || (*cur > '9')) \ 418070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard invalid = 1; \ 419070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { \ 420070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard mult /= 10; \ 421070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard num += (*cur - '0') * mult; \ 422070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; \ 423070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } \ 424070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 425070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 426070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 427070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * _xmlSchemaParseGMonth: 428070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @dt: pointer to a date structure 429070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @str: pointer to the string to analyze 430070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 431070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a xs:gMonth without time zone and fills in the appropriate 432070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * field of the @dt structure. @str is updated to point just after the 433070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * xs:gMonth. 434070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 435070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Returns 0 or the error code 436070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 437070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int 438070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard_xmlSchemaParseGMonth (xmlSchemaValDatePtr dt, const xmlChar **str) { 439070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const xmlChar *cur = *str; 440070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int ret = 0; 441070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 442070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_2_DIGITS(dt->mon, cur, ret); 443070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 444070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return ret; 445070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 446070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!VALID_MONTH(dt->mon)) 447070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 2; 448070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 449070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard *str = cur; 450070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 451070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard} 452070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 453070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 454070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * _xmlSchemaParseGDay: 455070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @dt: pointer to a date structure 456070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @str: pointer to the string to analyze 457070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 458070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a xs:gDay without time zone and fills in the appropriate 459070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * field of the @dt structure. @str is updated to point just after the 460070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * xs:gDay. 461070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 462070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Returns 0 or the error code 463070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 464070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int 465070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard_xmlSchemaParseGDay (xmlSchemaValDatePtr dt, const xmlChar **str) { 466070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const xmlChar *cur = *str; 467070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int ret = 0; 468070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 469070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_2_DIGITS(dt->day, cur, ret); 470070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 471070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return ret; 472070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 473070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!VALID_DAY(dt->day)) 474070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 2; 475070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 476070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard *str = cur; 477070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 478070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard} 479070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 480070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 481070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * _xmlSchemaParseTime: 482070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @dt: pointer to a date structure 483070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @str: pointer to the string to analyze 484070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 485070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a xs:time without time zone and fills in the appropriate 486070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * fields of the @dt structure. @str is updated to point just after the 487070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * xs:time. 488070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * In case of error, values of @dt fields are undefined. 489070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 490070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Returns 0 or the error code 491070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 492070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int 493070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard_xmlSchemaParseTime (xmlSchemaValDatePtr dt, const xmlChar **str) { 494070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const xmlChar *cur = *str; 495070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard unsigned int hour = 0; /* use temp var in case str is not xs:time */ 496070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int ret = 0; 497070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 498070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_2_DIGITS(hour, cur, ret); 499070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 500070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return ret; 501070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 502070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur != ':') 503070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 504070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 505070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 506070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* the ':' insures this string is xs:time */ 507070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->hour = hour; 508070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 509070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_2_DIGITS(dt->min, cur, ret); 510070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 511070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return ret; 512070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 513070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur != ':') 514070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 515070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 516070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 517070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_FLOAT(dt->sec, cur, ret); 518070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 519070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return ret; 520070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 521070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!VALID_TIME(dt)) 522070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 2; 523070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 524070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard *str = cur; 525070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 526070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard} 527070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 528070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 529070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * _xmlSchemaParseTimeZone: 530070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @dt: pointer to a date structure 531070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @str: pointer to the string to analyze 532070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 533070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a time zone without time zone and fills in the appropriate 534070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * field of the @dt structure. @str is updated to point just after the 535070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * time zone. 536070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 537070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Returns 0 or the error code 538070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 539070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int 540070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard_xmlSchemaParseTimeZone (xmlSchemaValDatePtr dt, const xmlChar **str) { 541070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const xmlChar *cur = *str; 542070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int ret = 0; 543070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 544070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (str == NULL) 545070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 546070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 547070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard switch (*cur) { 548070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case 0: 549070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->tz_flag = 0; 550070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->tzo = 0; 551070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard break; 552070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 553070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case 'Z': 554070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->tz_flag = 1; 555070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->tzo = 0; 556070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 557070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard break; 558070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 559070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case '+': 560070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case '-': { 561070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int isneg = 0, tmp = 0; 562070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard isneg = (*cur == '-'); 563070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 564070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 565070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 566070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_2_DIGITS(tmp, cur, ret); 567070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 568070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return ret; 569070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!VALID_HOUR(tmp)) 570070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 2; 571070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 572070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur != ':') 573070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 574070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 575070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 576070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->tzo = tmp * 60; 577070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 578070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_2_DIGITS(tmp, cur, ret); 579070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 580070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return ret; 581070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!VALID_MIN(tmp)) 582070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 2; 583070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 584070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->tzo += tmp; 585070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (isneg) 586070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->tzo = - dt->tzo; 587070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 588070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!VALID_TZO(dt->tzo)) 589070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 2; 590070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 5915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard dt->tz_flag = 1; 592070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard break; 593070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 594070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard default: 595070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 596070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 597070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 598070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard *str = cur; 599070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 600070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard} 601070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 602070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/**************************************************************** 603070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * * 604070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * XML Schema Dates/Times Datatypes Handling * 605070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * * 606070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ****************************************************************/ 607070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 608070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 609070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * PARSE_DIGITS: 610070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @num: the integer to fill in 611070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @cur: an #xmlChar * 612070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @num_type: an integer flag 613070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 614070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a digits integer and updates @num with the value. @cur is 615070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * updated to point just after the integer. 616070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * In case of error, @num_type is set to -1, values of @num and 617070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @cur are undefined. 618070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 619070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define PARSE_DIGITS(num, cur, num_type) \ 620070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((*cur < '0') || (*cur > '9')) \ 621070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard num_type = -1; \ 622070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else \ 623070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { \ 624070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard num = num * 10 + (*cur - '0'); \ 625070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; \ 626070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 627070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 628070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 629070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * PARSE_NUM: 630070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @num: the double to fill in 631070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @cur: an #xmlChar * 632070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @num_type: an integer flag 633070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 634070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Parses a float or integer and updates @num with the value. @cur is 635070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * updated to point just after the number. If the number is a float, 636070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * then it must have an integer part and a decimal part; @num_type will 637070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * be set to 1. If there is no decimal part, @num_type is set to zero. 638070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * In case of error, @num_type is set to -1, values of @num and 639070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @cur are undefined. 640070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 641070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define PARSE_NUM(num, cur, num_type) \ 642070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard num = 0; \ 643070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_DIGITS(num, cur, num_type); \ 644070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (!num_type && (*cur == '.')) { \ 645070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard double mult = 1; \ 646070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; \ 647070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((*cur < '0') || (*cur > '9')) \ 648070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard num_type = -1; \ 649070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else \ 650070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard num_type = 1; \ 651070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { \ 652070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard mult /= 10; \ 653070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard num += (*cur - '0') * mult; \ 654070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; \ 655070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } \ 656070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 657070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 658070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 6595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * xmlSchemaValidateDates: 660070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @type: the predefined type 661070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @dateTime: string to analyze 662070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @val: the return computed value 663070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 664070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Check that @dateTime conforms to the lexical space of one of the date types. 665070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * if true a value is computed and returned in @val. 666070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 667070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Returns 0 if this validates, a positive error code number otherwise 668070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * and -1 in case of internal or API error. 669070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 670070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int 671dda8f1ba9fb2e731e2dd6aa325ed07add7905ec3Daniel VeillardxmlSchemaValidateDates (xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 672118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard const xmlChar *dateTime, xmlSchemaValPtr *val) { 673070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaValPtr dt; 674070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int ret; 675070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const xmlChar *cur = dateTime; 676070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 677070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard#define RETURN_TYPE_IF_VALID(t) \ 678070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (IS_TZO_CHAR(*cur)) { \ 679070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur); \ 680070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret == 0) { \ 681070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur != 0) \ 682070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; \ 683070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->type = t; \ 684070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (val != NULL) \ 685070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard *val = dt; \ 686070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; \ 687070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } \ 688070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 689070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 690070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (dateTime == NULL) 691070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 692070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 693070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((*cur != '-') && (*cur < '0') && (*cur > '9')) 694070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 695070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 696070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt = xmlSchemaNewValue(XML_SCHEMAS_UNKNOWN); 697070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (dt == NULL) 698070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 699070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 700070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((cur[0] == '-') && (cur[1] == '-')) { 701070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* 702070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * It's an incomplete date (xs:gMonthDay, xs:gMonth or 703070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * xs:gDay) 704070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 705070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur += 2; 706070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 707070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* is it an xs:gDay? */ 708070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur == '-') { 709070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ++cur; 710070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseGDay(&(dt->value.date), &cur); 711070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 712070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 713070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 714070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard RETURN_TYPE_IF_VALID(XML_SCHEMAS_GDAY); 715070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 716070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 717070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 718070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 719070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* 720070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * it should be an xs:gMonthDay or xs:gMonth 721070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 722070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseGMonth(&(dt->value.date), &cur); 723070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 724070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 725070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 726070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur != '-') 727070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 728070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 729070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 730070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* is it an xs:gMonth? */ 731070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur == '-') { 732070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 733070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard RETURN_TYPE_IF_VALID(XML_SCHEMAS_GMONTH); 734070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 735070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 736070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 737070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* it should be an xs:gMonthDay */ 738070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseGDay(&(dt->value.date), &cur); 739070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 740070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 741070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 742070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard RETURN_TYPE_IF_VALID(XML_SCHEMAS_GMONTHDAY); 743070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 744070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 745070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 746070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 747070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* 748070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * It's a right-truncated date or an xs:time. 749070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Try to parse an xs:time then fallback on right-truncated dates. 750070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 751070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((*cur >= '0') && (*cur <= '9')) { 752070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseTime(&(dt->value.date), &cur); 753070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret == 0) { 754070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* it's an xs:time */ 755070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard RETURN_TYPE_IF_VALID(XML_SCHEMAS_TIME); 756070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 757070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 758070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 759070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* fallback on date parsing */ 760070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur = dateTime; 761070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 762070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseGYear(&(dt->value.date), &cur); 763070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 764070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 765070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 766070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* is it an xs:gYear? */ 767070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard RETURN_TYPE_IF_VALID(XML_SCHEMAS_GYEAR); 768070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 769070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur != '-') 770070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 771070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 772070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 773070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseGMonth(&(dt->value.date), &cur); 774070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 775070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 776070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 777070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* is it an xs:gYearMonth? */ 778070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard RETURN_TYPE_IF_VALID(XML_SCHEMAS_GYEARMONTH); 779070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 780070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur != '-') 781070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 782070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 783070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 784070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseGDay(&(dt->value.date), &cur); 785070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((ret != 0) || !VALID_DATE((&(dt->value.date)))) 786070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 787070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 788070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* is it an xs:date? */ 789070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard RETURN_TYPE_IF_VALID(XML_SCHEMAS_DATE); 790070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 791070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur != 'T') 792070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 793070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 794070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 795070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* it should be an xs:dateTime */ 796070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseTime(&(dt->value.date), &cur); 797070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret != 0) 798070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 799070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 800070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur); 801070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((ret != 0) || (*cur != 0) || !VALID_DATETIME((&(dt->value.date)))) 802070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 803070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 804070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dt->type = XML_SCHEMAS_DATETIME; 805070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 806070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (val != NULL) 807070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard *val = dt; 808070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 809070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 810070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 811070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillarderror: 812070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (dt != NULL) 813070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaFreeValue(dt); 814070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 815070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard} 816070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 817070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 8185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * xmlSchemaValidateDuration: 819070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @type: the predefined type 820070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @duration: string to analyze 821070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @val: the return computed value 822070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 823070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Check that @duration conforms to the lexical space of the duration type. 824070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * if true a value is computed and returned in @val. 825070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 826070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Returns 0 if this validates, a positive error code number otherwise 827070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * and -1 in case of internal or API error. 828070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 829070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int 830dda8f1ba9fb2e731e2dd6aa325ed07add7905ec3Daniel VeillardxmlSchemaValidateDuration (xmlSchemaTypePtr type ATTRIBUTE_UNUSED, 831118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard const xmlChar *duration, xmlSchemaValPtr *val) { 832070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const xmlChar *cur = duration; 833070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaValPtr dur; 834070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int isneg = 0; 835070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard unsigned int seq = 0; 836070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 837070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (duration == NULL) 838070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 839070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 840070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur == '-') { 841070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard isneg = 1; 842070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 843070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 844070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 845070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* duration must start with 'P' (after sign) */ 846070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur++ != 'P') 847070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 848070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 849070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION); 850070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (dur == NULL) 851070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 852070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 853070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard while (*cur != 0) { 854070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard double num; 855070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard int num_type = 0; /* -1 = invalid, 0 = int, 1 = floating */ 856070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const xmlChar desig[] = {'Y', 'M', 'D', 'H', 'M', 'S'}; 857070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard const double multi[] = { 0.0, 0.0, 86400.0, 3600.0, 60.0, 1.0, 0.0}; 858070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 859070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* input string should be empty or invalid date/time item */ 860070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (seq >= sizeof(desig)) 861070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 862070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 863070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* T designator must be present for time items */ 864070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur == 'T') { 865070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (seq <= 3) { 866070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard seq = 3; 867070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 868070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } else 869070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 870070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } else if (seq == 3) 871070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 872070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 873070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* parse the number portion of the item */ 874070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard PARSE_NUM(num, cur, num_type); 875070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 876070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((num_type == -1) || (*cur == 0)) 877070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 878070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 879070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* update duration based on item type */ 880070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard while (seq < sizeof(desig)) { 881070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (*cur == desig[seq]) { 882070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 883070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* verify numeric type; only seconds can be float */ 884070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((num_type != 0) && (seq < (sizeof(desig)-1))) 885070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 886070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 887070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard switch (seq) { 888070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case 0: 889070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dur->value.dur.mon = (long)num * 12; 890070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard break; 891070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case 1: 892070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dur->value.dur.mon += (long)num; 893070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard break; 894070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard default: 895070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* convert to seconds using multiplier */ 896070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dur->value.dur.sec += num * multi[seq]; 897070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard seq++; 898070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard break; 899070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 900070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 901070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard break; /* exit loop */ 902070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 903070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* no date designators found? */ 904070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (++seq == 3) 905070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard goto error; 906070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 907070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard cur++; 908070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 909070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 910070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (isneg) { 911070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dur->value.dur.mon = -dur->value.dur.mon; 912070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dur->value.dur.day = -dur->value.dur.day; 913070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard dur->value.dur.sec = -dur->value.dur.sec; 914070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 915070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 916070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (val != NULL) 917070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard *val = dur; 918070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 919070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 920070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 921070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillarderror: 922070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (dur != NULL) 923070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmlSchemaFreeValue(dur); 924070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 925070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard} 926070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 9274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 9284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaValidatePredefinedType: 9294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type: the predefined type 9304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @value: the value to check 9314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @val: the return computed value 9324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 9334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Check that a value conforms to the lexical space of the predefined type. 9344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * if true a value is computed and returned in @val. 9354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 9364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns 0 if this validates, a positive error code number otherwise 9374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * and -1 in case of internal or API error. 9384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 9394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint 9404255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaValidatePredefinedType(xmlSchemaTypePtr type, const xmlChar *value, 9414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaValPtr *val) { 9424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaValPtr v; 9434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 9444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (xmlSchemaTypesInitialized == 0) 9454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 9464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (type == NULL) 9474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 9485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 9494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (val != NULL) 9504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *val = NULL; 9514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (type == xmlSchemaTypeStringDef) { 9524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 9534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (type == xmlSchemaTypeAnyTypeDef) { 9544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 9554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (type == xmlSchemaTypeAnySimpleTypeDef) { 9564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 9574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (type == xmlSchemaTypeNmtoken) { 9584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (xmlValidateNmtokenValue(value)) 9594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 9604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 9614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (type == xmlSchemaTypeDecimalDef) { 9624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard const xmlChar *cur = value, *tmp; 9635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard int frac = 0, len, neg = 0; 9644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard unsigned long base = 0; 9654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == NULL) 9664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 9674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (*cur == '+') 9684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 9694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (*cur == '-') { 9704255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard neg = 1; 9714255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 9724255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9734255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = cur; 9744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 9754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard base = base * 10 + (*cur - '0'); 9764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 9774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard len = cur - tmp; 9794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (*cur == '.') { 9804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 9814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = cur; 9824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 9834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard base = base * 10 + (*cur - '0'); 9844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 9854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard frac = cur - tmp; 9874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (*cur != 0) 9894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 9904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (val != NULL) { 9914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL); 9924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (v != NULL) { 9934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.base = base; 9944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.sign = neg; 9954255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.frac = frac; 9965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard v->value.decimal.total = frac + len; 9974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *val = v; 9984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 9994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 1001070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } else if (type == xmlSchemaTypeDurationDef) { 10025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return xmlSchemaValidateDuration(type, value, val); 1003070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } else if ((type == xmlSchemaTypeDatetimeDef) || 1004070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (type == xmlSchemaTypeTimeDef) || 1005070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (type == xmlSchemaTypeDateDef) || 1006070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (type == xmlSchemaTypeGYearDef) || 1007070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (type == xmlSchemaTypeGYearMonthDef) || 1008070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (type == xmlSchemaTypeGMonthDef) || 1009070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (type == xmlSchemaTypeGMonthDayDef) || 1010070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard (type == xmlSchemaTypeGDayDef)) { 10115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return xmlSchemaValidateDates(type, value, val); 10124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (type == xmlSchemaTypePositiveIntegerDef) { 10134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard const xmlChar *cur = value; 10144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard unsigned long base = 0; 10154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int total = 0; 10164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == NULL) 10174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 10184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (*cur == '+') 10194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 10204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 10214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard base = base * 10 + (*cur - '0'); 10224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard total++; 10234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 10244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (*cur != 0) 10264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 10274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (val != NULL) { 10284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL); 10294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (v != NULL) { 10304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.base = base; 10314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.sign = 0; 10324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.frac = 0; 10334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.total = total; 10344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *val = v; 10354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 10384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (type == xmlSchemaTypeNonNegativeIntegerDef) { 10394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard const xmlChar *cur = value; 10404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard unsigned long base = 0; 10414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int total = 0; 10424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int sign = 0; 10434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (cur == NULL) 10444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 10454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (*cur == '-') { 10464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard sign = 1; 10474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 10484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else if (*cur == '+') 10494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 10504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 10514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard base = base * 10 + (*cur - '0'); 10524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard total++; 10534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard cur++; 10544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (*cur != 0) 10564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 10574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((sign == 1) && (base != 0)) 10584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 10594255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (val != NULL) { 10604255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL); 10614255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (v != NULL) { 10624255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.base = base; 10634255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.sign = 0; 10644255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.frac = 0; 10654255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard v->value.decimal.total = total; 10664255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard *val = v; 10674255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10684255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 10694255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 107084d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard } else if (type == xmlSchemaTypeFloatDef) { 107184d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard const xmlChar *cur = value, *tmp; 107284d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard int frac = 0, len, neg = 0; 107384d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard unsigned long base = 0; 107484d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard if (cur == NULL) 107584d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard return(1); 107684d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard if (*cur == '+') 107784d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard cur++; 107884d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard else if (*cur == '-') { 107984d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard neg = 1; 108084d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard cur++; 108184d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard } 108284d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard tmp = cur; 108384d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 108484d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard base = base * 10 + (*cur - '0'); 108584d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard cur++; 108684d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard } 108784d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard len = cur - tmp; 108884d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard if (*cur == '.') { 108984d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard cur++; 109084d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard tmp = cur; 109184d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard while ((*cur >= '0') && (*cur <= '9')) { 109284d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard base = base * 10 + (*cur - '0'); 109384d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard cur++; 109484d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard } 109584d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard frac = cur - tmp; 109684d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard } 1097b5c05735785b4d60d0876f2604229f85eb1a9cf1Daniel Veillard TODO 1098b5c05735785b4d60d0876f2604229f85eb1a9cf1Daniel Veillard return(0); 109984d70a462ff443b310ca90fdce722f81261dc93bDaniel Veillard } else if (type == xmlSchemaTypeDoubleDef) { 1100b5c05735785b4d60d0876f2604229f85eb1a9cf1Daniel Veillard TODO 1101b5c05735785b4d60d0876f2604229f85eb1a9cf1Daniel Veillard return(0); 11024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } else { 11034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard TODO 11044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 11054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 11074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 11094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaCompareDecimals: 11104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @x: a first decimal value 11114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @y: a second decimal value 11124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 11134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Compare 2 decimals 11144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 11154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns -1 if x < y, 0 if x == y, 1 if x > y and -2 in case of error 11164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 11174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardstatic int 11184255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaCompareDecimals(xmlSchemaValPtr x, xmlSchemaValPtr y) 11194255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard{ 11204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard xmlSchemaValPtr swp; 11214255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int order = 1; 11224255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard unsigned long tmp; 11234255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11244255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((x->value.decimal.sign) && (x->value.decimal.sign)) 11254255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard order = -1; 11264255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (x->value.decimal.sign) 11274255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (-1); 11284255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard else if (y->value.decimal.sign) 11294255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (1); 11304255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (x->value.decimal.frac == y->value.decimal.frac) { 11314255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (x->value.decimal.base < y->value.decimal.base) 11324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (-1); 11334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (x->value.decimal.base > y->value.decimal.base); 11344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (y->value.decimal.frac > x->value.decimal.frac) { 11364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard swp = y; 11374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard y = x; 11384255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard x = swp; 11394255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard order = -order; 11404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 11414255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = 11424255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard x->value.decimal.base / powten[x->value.decimal.frac - 11434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard y->value.decimal.frac]; 11444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp > y->value.decimal.base) 11454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (order); 11464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (tmp < y->value.decimal.base) 11474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (-order); 11484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard tmp = 11494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard y->value.decimal.base * powten[x->value.decimal.frac - 11504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard y->value.decimal.frac]; 11514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (x->value.decimal.base < tmp) 11524255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (-order); 11534255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (x->value.decimal.base == tmp) 11544255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (0); 11554255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return (order); 11564255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 11574255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 11584255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 1159070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * xmlSchemaCompareDurations: 1160070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @x: a first duration value 1161070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * @y: a second duration value 1162070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 1163070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Compare 2 durations 1164070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * 1165070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in 1166070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard * case of error 1167070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard */ 1168070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillardstatic int 1169070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel VeillardxmlSchemaCompareDurations(xmlSchemaValPtr x, xmlSchemaValPtr y) 1170070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard{ 1171070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard long carry, mon, day; 1172070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard double sec; 1173070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard long xmon, xday, myear, lyear, minday, maxday; 1174070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard static const long dayRange [2][12] = { 1175070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard { 0, 28, 59, 89, 120, 150, 181, 212, 242, 273, 303, 334, }, 1176070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard { 0, 31, 62, 92, 123, 153, 184, 215, 245, 276, 306, 337} }; 1177070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1178070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((x == NULL) || (y == NULL)) 11795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -2; 1180070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1181070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* months */ 1182070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard mon = x->value.dur.mon - y->value.dur.mon; 1183070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1184070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* seconds */ 1185070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard sec = x->value.dur.sec - y->value.dur.sec; 1186070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard carry = (long)sec / SECS_PER_DAY; 1187070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard sec -= (double)(carry * SECS_PER_DAY); 1188070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1189070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* days */ 1190070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard day = x->value.dur.day - y->value.dur.day + carry; 1191070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1192070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* easy test */ 1193070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (mon == 0) { 1194070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (day == 0) 1195070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (sec == 0.0) 1196070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 1197070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else if (sec < 0.0) 1198070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 1199070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else 1200070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 1201070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else if (day < 0) 1202070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 1203070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else 1204070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 1205070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 1206070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1207070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (mon > 0) { 1208070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((day >= 0) && (sec >= 0.0)) 1209070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 1210070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else { 1211070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmon = mon; 1212070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xday = -day; 1213070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 1214070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } else if ((day <= 0) && (sec <= 0.0)) { 1215070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 1216070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } else { 1217070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmon = -mon; 1218070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xday = day; 1219070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 1220070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1221070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard myear = xmon / 12; 1222070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard lyear = myear / 4; 1223070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard minday = (myear * 365) + (lyear != 0 ? lyear - 1 : 0); 1224070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard maxday = (myear * 365) + (lyear != 0 ? lyear + 1 : 0); 1225070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1226070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard xmon = xmon % 12; 1227070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard minday += dayRange[0][xmon]; 1228070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard maxday += dayRange[1][xmon]; 1229070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1230070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (maxday < xday) 1231070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 1; 1232070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard else if (minday > xday) 1233070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return -1; 1234070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1235070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard /* indeterminate */ 12365a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 2; 12375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard} 12385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/* 12405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * macros for adding date/times and durations 12415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 12425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define FQUOTIENT(a,b) (floor(((double)a/(double)b))) 12435a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define MODULO(a,b) (a - FQUOTIENT(a,b) * b) 12445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define FQUOTIENT_RANGE(a,low,high) (FQUOTIENT((a-low),(high-low))) 12455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define MODULO_RANGE(a,low,high) ((MODULO((a-low),(high-low)))+low) 12465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/** 12485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * _xmlSchemaDateAdd: 12495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * @dt: an #xmlSchemaValPtr 12505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * @dur: an #xmlSchemaValPtr of type #XS_DURATION 12515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 12525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Compute a new date/time from @dt and @dur. This function assumes @dt 12535a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * is either #XML_SCHEMAS_DATETIME, #XML_SCHEMAS_DATE, #XML_SCHEMAS_GYEARMONTH, 12545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * or #XML_SCHEMAS_GYEAR. 12555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 12565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Returns date/time pointer or NULL. 12575a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 12585a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic xmlSchemaValPtr 12595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard_xmlSchemaDateAdd (xmlSchemaValPtr dt, xmlSchemaValPtr dur) 12605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{ 12615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlSchemaValPtr ret; 12625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard long carry, tempdays, temp; 12635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlSchemaValDatePtr r, d; 12645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlSchemaValDurationPtr u; 12655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if ((dt == NULL) || (dur == NULL)) 12675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return NULL; 12685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ret = xmlSchemaNewValue(dt->type); 12705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (ret == NULL) 12715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return NULL; 12725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r = &(ret->value.date); 12745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard d = &(dt->value.date); 12755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard u = &(dur->value.dur); 12765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* normalization */ 12785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (d->mon == 0) 12795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard d->mon = 1; 12805a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* normalize for time zone offset */ 12825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard u->sec -= (d->tzo * 60); 12835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard d->tzo = 0; 12845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* normalization */ 12865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (d->day == 0) 12875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard d->day = 1; 12885a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* month */ 12905a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry = d->mon + u->mon; 12915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->mon = MODULO_RANGE(carry, 1, 13); 12925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry = FQUOTIENT_RANGE(carry, 1, 13); 12935a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 12945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* year (may be modified later) */ 12955a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->year = d->year + carry; 12965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (r->year == 0) { 12975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (d->year > 0) 12985a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->year--; 12995a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else 13005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->year++; 13015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 13025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* time zone */ 13045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->tzo = d->tzo; 13055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->tz_flag = d->tz_flag; 13065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* seconds */ 13085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->sec = d->sec + u->sec; 13095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry = FQUOTIENT((long)r->sec, 60); 13105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (r->sec != 0.0) { 13115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->sec = MODULO(r->sec, 60.0); 13125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 13135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* minute */ 13155a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry += d->min; 13165a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->min = MODULO(carry, 60); 13175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry = FQUOTIENT(carry, 60); 13185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* hours */ 13205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry += d->hour; 13215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->hour = MODULO(carry, 24); 13225a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry = FQUOTIENT(carry, 24); 13235a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13245a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* 13255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * days 13265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Note we use tempdays because the temporary values may need more 13275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * than 5 bits 13285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 13295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if ((VALID_YEAR(r->year)) && (VALID_MONTH(r->mon)) && 13305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (d->day > MAX_DAYINMONTH(r->year, r->mon))) 13315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard tempdays = MAX_DAYINMONTH(r->year, r->mon); 13325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (d->day < 1) 13335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard tempdays = 1; 13345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else 13355a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard tempdays = d->day; 13365a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard tempdays += u->day + carry; 13385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard while (1) { 13405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (tempdays < 1) { 13415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard long tmon = MODULO_RANGE(r->mon-1, 1, 13); 13425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard long tyr = r->year + FQUOTIENT_RANGE(r->mon-1, 1, 13); 13435a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (tyr == 0) 13445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard tyr--; 13455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard tempdays += MAX_DAYINMONTH(tyr, tmon); 13465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry = -1; 13475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } else if (tempdays > MAX_DAYINMONTH(r->year, r->mon)) { 13485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard tempdays = tempdays - MAX_DAYINMONTH(r->year, r->mon); 13495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard carry = 1; 13505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } else 13515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 13525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13535a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard temp = r->mon + carry; 13545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->mon = MODULO_RANGE(temp, 1, 13); 13555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->year = r->year + FQUOTIENT_RANGE(temp, 1, 13); 13565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (r->year == 0) { 13575a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (temp < 1) 13585a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->year--; 13595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else 13605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->year++; 13615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 13625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 13635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard r->day = tempdays; 13655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* 13675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * adjust the date/time type to the date values 13685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 13695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (ret->type != XML_SCHEMAS_DATETIME) { 13705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if ((r->hour) || (r->min) || (r->sec)) 13715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ret->type = XML_SCHEMAS_DATETIME; 13725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (ret->type != XML_SCHEMAS_DATE) { 13735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if ((r->mon != 1) && (r->day != 1)) 13745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ret->type = XML_SCHEMAS_DATE; 13755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if ((ret->type != XML_SCHEMAS_GYEARMONTH) && (r->mon != 1)) 13765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ret->type = XML_SCHEMAS_GYEARMONTH; 13775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 13785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 13795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13805a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return ret; 13815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard} 13825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/** 13845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * xmlSchemaDupVal: 13855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * @v: value to duplicate 13865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 13875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * returns a duplicated value. 13885a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 13895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic xmlSchemaValPtr 13905a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardxmlSchemaDupVal (xmlSchemaValPtr v) 13915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{ 13925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlSchemaValPtr ret = xmlSchemaNewValue(v->type); 13935a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (ret == NULL) 13945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return ret; 13955a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 13965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard memcpy(ret, v, sizeof(xmlSchemaVal)); 13975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return ret; 13985a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard} 13995a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/** 14015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * xmlSchemaDateNormalize: 14025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * @dt: an #xmlSchemaValPtr 14035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 14045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Normalize @dt to GMT time. 14055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 14065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 14075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic xmlSchemaValPtr 14085a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardxmlSchemaDateNormalize (xmlSchemaValPtr dt, double offset) 14095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{ 14105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlSchemaValPtr dur, ret; 14115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (dt == NULL) 14135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return NULL; 14145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14155a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (((dt->type != XML_SCHEMAS_TIME) && 14165a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (dt->type != XML_SCHEMAS_DATETIME)) || (dt->value.date.tzo == 0)) 14175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return xmlSchemaDupVal(dt); 14185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION); 14205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (dur == NULL) 14215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return NULL; 14225a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14235a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard dur->value.date.sec -= offset; 14245a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ret = _xmlSchemaDateAdd(dt, dur); 14265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (ret == NULL) 14275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return NULL; 14285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlSchemaFreeValue(dur); 14305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* ret->value.date.tzo = 0; */ 14325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return ret; 14335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard} 14345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14355a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/** 14365a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * _xmlSchemaDateCastYMToDays: 14375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * @dt: an #xmlSchemaValPtr 14385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 14395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Convert mon and year of @dt to total number of days. Take the 14405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * number of years since (or before) 1 AD and add the number of leap 14415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * years. This is a function because negative 14425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * years must be handled a little differently and there is no zero year. 14435a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 14445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Returns number of days. 14455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 14465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic long 14475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard_xmlSchemaDateCastYMToDays (const xmlSchemaValPtr dt) 14485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{ 14495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard long ret; 14505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (dt->value.date.year < 0) 14525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ret = (dt->value.date.year * 365) + 14535a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (((dt->value.date.year+1)/4)-((dt->value.date.year+1)/100)+ 14545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ((dt->value.date.year+1)/400)) + 14555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard DAY_IN_YEAR(0, dt->value.date.mon, dt->value.date.year); 14565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else 14575a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ret = ((dt->value.date.year-1) * 365) + 14585a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (((dt->value.date.year-1)/4)-((dt->value.date.year-1)/100)+ 14595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ((dt->value.date.year-1)/400)) + 14605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard DAY_IN_YEAR(0, dt->value.date.mon, dt->value.date.year); 14615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return ret; 14635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard} 14645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/** 14665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * TIME_TO_NUMBER: 14675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * @dt: an #xmlSchemaValPtr 14685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 14695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Calculates the number of seconds in the time portion of @dt. 14705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 14715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Returns seconds. 14725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 14735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard#define TIME_TO_NUMBER(dt) \ 14745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ((double)((dt->value.date.hour * SECS_PER_HOUR) + \ 14755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (dt->value.date.min * SECS_PER_MIN)) + dt->value.date.sec) 14765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard/** 14785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * xmlSchemaCompareDates: 14795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * @x: a first date/time value 14805a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * @y: a second date/time value 14815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 14825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Compare 2 date/times 14835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * 14845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in 14855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * case of error 14865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 14875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillardstatic int 14885a872413fd58df3095979521d9a03ad03cab73a5Daniel VeillardxmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y) 14895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard{ 14905a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard unsigned char xmask, ymask, xor_mask, and_mask; 14915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmlSchemaValPtr p1, p2, q1, q2; 14925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard long p1d, p2d, q1d, q2d; 14935a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if ((x == NULL) || (y == NULL)) 14955a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -2; 14965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (x->value.date.tz_flag) { 14985a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 14995a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (!y->value.date.tz_flag) { 15005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard p1 = xmlSchemaDateNormalize(x, 0); 15015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day; 15025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* normalize y + 14:00 */ 15035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard q1 = xmlSchemaDateNormalize(y, (14 * SECS_PER_HOUR)); 15045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 15055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day; 1506fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (p1d < q1d) { 1507fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1508fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 15095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 1510fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else if (p1d == q1d) { 15115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard double sec; 15125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 15135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1); 1514fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (sec < 0.0) { 1515fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1516fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 15175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 1518fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else { 15195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* normalize y - 14:00 */ 15205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard q2 = xmlSchemaDateNormalize(y, -(14 * SECS_PER_HOUR)); 15215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard q2d = _xmlSchemaDateCastYMToDays(q2) + q2->value.date.day; 1522fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1523fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 1524fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q2); 15255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (p1d > q2d) 15265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 15275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (p1d == q2d) { 15285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q2); 15295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (sec > 0.0) 15305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 15315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else 15325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 2; /* indeterminate */ 15335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 15345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 1535fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else { 1536fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1537fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 1538fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } 15395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 15405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } else if (y->value.date.tz_flag) { 15415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard q1 = xmlSchemaDateNormalize(y, 0); 15425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day; 15435a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 15445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* normalize x - 14:00 */ 15455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard p1 = xmlSchemaDateNormalize(x, -(14 * SECS_PER_HOUR)); 15465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day; 15475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 1548fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (p1d < q1d) { 1549fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1550fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 15515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 1552fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else if (p1d == q1d) { 15535a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard double sec; 15545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 15555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1); 1556fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (sec < 0.0) { 1557fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1558fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 15595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 1560fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else { 15615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* normalize x + 14:00 */ 15625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard p2 = xmlSchemaDateNormalize(x, (14 * SECS_PER_HOUR)); 15635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard p2d = _xmlSchemaDateCastYMToDays(p2) + p2->value.date.day; 15645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 1565fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1566fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 1567fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p2); 15685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (p2d > q1d) 15695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 15705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (p2d == q1d) { 15715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard sec = TIME_TO_NUMBER(p2) - TIME_TO_NUMBER(q1); 15725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (sec > 0.0) 15735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 15745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else 15755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 2; /* indeterminate */ 15765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 15775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 1578fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else { 1579fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1580fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 15815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 15825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 15835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 15845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* 15855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * if the same type then calculate the difference 15865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard */ 15875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (x->type == y->type) { 15885a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard q1 = xmlSchemaDateNormalize(y, 0); 15895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day; 15905a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 15915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard p1 = xmlSchemaDateNormalize(x, 0); 15925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day; 15935a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 1594fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard if (p1d < q1d) { 1595fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1596fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 15975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 1598fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else if (p1d > q1d) { 1599fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1600fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 16015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 1602fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard } else { 16035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard double sec; 16045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 16055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1); 1606fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(p1); 1607fdc9156a753e839386d9f82b7a962f9779de862cDaniel Veillard xmlSchemaFreeValue(q1); 16085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (sec < 0.0) 16095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 16105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (sec > 0.0) 16115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 16125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 16135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 16145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 0; 16155a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 16165a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 16175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard switch (x->type) { 16185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_DATETIME: 16195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0xf; 16205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_DATE: 16225a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0x7; 16235a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16245a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GYEAR: 16255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0x1; 16265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GMONTH: 16285a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0x2; 16295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16305a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GDAY: 16315a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0x3; 16325a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16335a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GYEARMONTH: 16345a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0x3; 16355a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16365a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GMONTHDAY: 16375a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0x6; 16385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_TIME: 16405a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0x8; 16415a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16425a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard default: 16435a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xmask = 0; 16445a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16455a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 16465a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 16475a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard switch (y->type) { 16485a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_DATETIME: 16495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0xf; 16505a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16515a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_DATE: 16525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0x7; 16535a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16545a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GYEAR: 16555a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0x1; 16565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16575a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GMONTH: 16585a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0x2; 16595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GDAY: 16615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0x3; 16625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GYEARMONTH: 16645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0x3; 16655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GMONTHDAY: 16675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0x6; 16685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_TIME: 16705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0x8; 16715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard default: 16735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard ymask = 0; 16745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard break; 16755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 16765a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 16775a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard xor_mask = xmask ^ ymask; /* mark type differences */ 16785a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard and_mask = xmask & ymask; /* mark field specification */ 16795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 16805a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* year */ 16815a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (xor_mask & 1) 16825a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 2; /* indeterminate */ 16835a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (and_mask & 1) { 16845a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (x->value.date.year < y->value.date.year) 16855a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 16865a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (x->value.date.year > y->value.date.year) 16875a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 16885a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 16895a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 16905a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* month */ 16915a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (xor_mask & 2) 16925a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 2; /* indeterminate */ 16935a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (and_mask & 2) { 16945a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (x->value.date.mon < y->value.date.mon) 16955a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 16965a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (x->value.date.mon > y->value.date.mon) 16975a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 16985a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 16995a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 17005a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* day */ 17015a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (xor_mask & 4) 17025a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 2; /* indeterminate */ 17035a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (and_mask & 4) { 17045a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (x->value.date.day < y->value.date.day) 17055a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 17065a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (x->value.date.day > y->value.date.day) 17075a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 17085a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 17095a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 17105a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* time */ 17115a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (xor_mask & 8) 17125a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 2; /* indeterminate */ 17135a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (and_mask & 8) { 17145a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if (x->value.date.hour < y->value.date.hour) 17155a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 17165a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (x->value.date.hour > y->value.date.hour) 17175a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 17185a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (x->value.date.min < y->value.date.min) 17195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 17205a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (x->value.date.min > y->value.date.min) 17215a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 17225a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (x->value.date.sec < y->value.date.sec) 17235a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -1; 17245a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard else if (x->value.date.sec > y->value.date.sec) 17255a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return 1; 17265a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard } 17275a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 1728070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return 0; 1729070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard} 1730070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard 1731070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard/** 17324255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaCompareValues: 17334255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @x: a first value 17344255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @y: a second value 17354255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 17364255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Compare 2 values 17374255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 17385a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in 17395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard * case of error 17404255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 1741e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillardstatic int 17424255d504151db75c17f85192ce74f45dd2d65533Daniel VeillardxmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) { 17434255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if ((x == NULL) || (y == NULL)) 17444255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-2); 17454255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 17464255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (x->type) { 17474255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_SCHEMAS_STRING: 17484255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard TODO 17494255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_SCHEMAS_DECIMAL: 17504255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (y->type == XML_SCHEMAS_DECIMAL) 17514255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(xmlSchemaCompareDecimals(x, y)); 17525a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return(-2); 1753070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case XML_SCHEMAS_DURATION: 1754070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (y->type == XML_SCHEMAS_DURATION) 1755070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(xmlSchemaCompareDurations(x, y)); 17565a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return(-2); 17575a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_TIME: 17585a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GDAY: 17595a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GMONTH: 17605a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GMONTHDAY: 17615a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GYEAR: 17625a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_GYEARMONTH: 17635a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_DATE: 17645a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard case XML_SCHEMAS_DATETIME: 17655a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard if ((y->type == XML_SCHEMAS_DATETIME) || 17665a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (y->type == XML_SCHEMAS_TIME) || 17675a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (y->type == XML_SCHEMAS_GDAY) || 17685a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (y->type == XML_SCHEMAS_GMONTH) || 17695a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (y->type == XML_SCHEMAS_GMONTHDAY) || 17705a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (y->type == XML_SCHEMAS_GYEAR) || 17715a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (y->type == XML_SCHEMAS_DATE) || 17725a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard (y->type == XML_SCHEMAS_GYEARMONTH)) 17735a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return (xmlSchemaCompareDates(x, y)); 17745a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard 17755a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return (-2); 17764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 17774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard TODO 17784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 17795a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard return -2; 17804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 17814255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 17824255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard/** 17834255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * xmlSchemaValidateFacet: 17844255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @type: the type declaration 17854255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @facet: the facet to check 17864255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @value: the lexical repr of the value to validate 17874255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * @val: the precomputed value 17884255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 17894255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Check a value against a facet condition 17904255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * 17914255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * Returns 0 if the element is schemas valid, a positive error code 17924255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard * number otherwise and -1 in case of internal or API error. 17934255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard */ 17944255d504151db75c17f85192ce74f45dd2d65533Daniel Veillardint 1795dda8f1ba9fb2e731e2dd6aa325ed07add7905ec3Daniel VeillardxmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED, 1796118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard xmlSchemaFacetPtr facet, 17974255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard const xmlChar *value, xmlSchemaValPtr val) 17984255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard{ 17994255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard int ret; 18004255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 18014255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard switch (facet->type) { 18024255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_SCHEMA_FACET_PATTERN: 18034255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlRegexpExec(facet->regexp, value); 18044255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 1) 18054255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 18064255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == 0) { 18074255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard TODO /* error code */ 18084255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 18094255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18104255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(ret); 18114255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard case XML_SCHEMA_FACET_MAXEXCLUSIVE: 18124255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard ret = xmlSchemaCompareValues(val, facet->val); 18134255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == -2) { 18144255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard TODO /* error code */ 18154255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(-1); 18164255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18174255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard if (ret == -1) 18184255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 18195a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* error code */ 18204255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(1); 1821070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case XML_SCHEMA_FACET_MAXINCLUSIVE: 1822070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = xmlSchemaCompareValues(val, facet->val); 1823070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret == -2) { 1824070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard TODO /* error code */ 1825070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(-1); 1826070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 1827070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((ret == -1) || (ret == 0)) 1828070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(0); 18295a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* error code */ 1830070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(1); 1831070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case XML_SCHEMA_FACET_MINEXCLUSIVE: 1832070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = xmlSchemaCompareValues(val, facet->val); 1833070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret == -2) { 1834070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard TODO /* error code */ 1835070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(-1); 1836070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 1837070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret == 1) 1838070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(0); 18395a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* error code */ 1840070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(1); 1841070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard case XML_SCHEMA_FACET_MININCLUSIVE: 1842070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard ret = xmlSchemaCompareValues(val, facet->val); 1843070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if (ret == -2) { 1844070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard TODO /* error code */ 1845070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(-1); 1846070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard } 1847070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard if ((ret == 1) || (ret == 0)) 1848070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(0); 18495a872413fd58df3095979521d9a03ad03cab73a5Daniel Veillard /* error code */ 1850070803b315fa3a5b1167bdda5a2d247bcc526ed2Daniel Veillard return(1); 18518651f5365c182ce5c52fe1cdc2b9d72b2ecc34e2Daniel Veillard case XML_SCHEMA_FACET_WHITESPACE: 18528651f5365c182ce5c52fe1cdc2b9d72b2ecc34e2Daniel Veillard TODO /* whitespaces */ 18538651f5365c182ce5c52fe1cdc2b9d72b2ecc34e2Daniel Veillard return(0); 1854e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard case XML_SCHEMA_FACET_MAXLENGTH: 1855e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if ((facet->val != NULL) && 1856e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard (facet->val->type == XML_SCHEMAS_DECIMAL) && 1857e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard (facet->val->value.decimal.frac == 0)) { 1858118aed78f360f51d182770e62b251ef324707aa2Daniel Veillard unsigned int len; 1859e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard 1860e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (facet->val->value.decimal.sign == 1) 1861e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(1); 1862e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard len = xmlUTF8Strlen(value); 1863e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard if (len > facet->val->value.decimal.base) 1864e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(1); 1865e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(0); 1866e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard } 1867e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard TODO /* error code */ 1868e19fc23b6427f4df516af7b3f6df7baa942e4207Daniel Veillard return(1); 186988c5891a25c1151a89f021e915d9efb7e58bfbf7Daniel Veillard case XML_SCHEMA_FACET_ENUMERATION: 187088c5891a25c1151a89f021e915d9efb7e58bfbf7Daniel Veillard if ((facet->value != NULL) && 187188c5891a25c1151a89f021e915d9efb7e58bfbf7Daniel Veillard (xmlStrEqual(facet->value, value))) 187288c5891a25c1151a89f021e915d9efb7e58bfbf7Daniel Veillard return(0); 187388c5891a25c1151a89f021e915d9efb7e58bfbf7Daniel Veillard return(1); 18744255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard default: 18754255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard TODO 18764255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard } 18774255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard return(0); 18784255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard} 18794255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard 18804255d504151db75c17f85192ce74f45dd2d65533Daniel Veillard#endif /* LIBXML_SCHEMAS_ENABLED */ 1881