2002-04-16 19:50:10 +04:00
/*
* schemastypes . c : implementation of the XML Schema Datatypes
* definition and validity checking
*
* See Copyright for the status of this software .
*
* Daniel Veillard < veillard @ redhat . com >
*/
2017-08-28 15:30:43 +03:00
/* To avoid EBCDIC trouble when parsing on zOS */
# if defined(__MVS__)
# pragma convert("ISO8859-1")
# endif
2002-04-16 19:50:10 +04:00
# define IN_LIBXML
# include "libxml.h"
# ifdef LIBXML_SCHEMAS_ENABLED
2023-09-21 01:44:50 +03:00
# include <stdlib.h>
2002-04-16 19:50:10 +04:00
# include <string.h>
2022-03-02 02:29:17 +03:00
# include <math.h>
# include <float.h>
2002-04-16 19:50:10 +04:00
# include <libxml/xmlmemory.h>
# include <libxml/parser.h>
# include <libxml/parserInternals.h>
# include <libxml/hash.h>
2003-02-06 11:22:32 +03:00
# include <libxml/xpath.h>
# include <libxml/uri.h>
2023-11-07 23:08:01 +03:00
# include <string.h>
2002-04-16 19:50:10 +04:00
# include <libxml/xmlschemas.h>
# include <libxml/schemasInternals.h>
# include <libxml/xmlschemastypes.h>
2022-08-26 02:22:33 +03:00
# include "private/error.h"
2024-06-16 00:53:04 +03:00
# ifndef isnan
# define isnan(x) (!((x) == (x)))
2004-11-09 19:17:02 +03:00
# endif
2002-04-16 19:50:10 +04:00
# define XML_SCHEMAS_NAMESPACE_NAME \
( const xmlChar * ) " http://www.w3.org/2001/XMLSchema "
2005-02-17 14:10:44 +03:00
# define IS_WSP_REPLACE_CH(c) ((((c) == 0x9) || ((c) == 0xa)) || \
( ( c ) = = 0xd ) )
# define IS_WSP_SPACE_CH(c) ((c) == 0x20)
2005-03-16 19:29:18 +03:00
# define IS_WSP_BLANK_CH(c) IS_BLANK_CH(c)
2002-05-03 11:29:38 +04:00
/* Date value */
typedef struct _xmlSchemaValDate xmlSchemaValDate ;
typedef xmlSchemaValDate * xmlSchemaValDatePtr ;
struct _xmlSchemaValDate {
long year ;
unsigned int mon : 4 ; /* 1 <= mon <= 12 */
unsigned int day : 5 ; /* 1 <= day <= 31 */
2016-04-11 21:03:19 +03:00
unsigned int hour : 5 ; /* 0 <= hour <= 24 */
2002-05-03 11:29:38 +04:00
unsigned int min : 6 ; /* 0 <= min <= 59 */
double sec ;
2019-09-30 18:04:54 +03:00
unsigned int tz_flag : 1 ; /* is tzo explicitly set? */
2005-05-12 17:10:22 +04:00
signed int tzo : 12 ; /* -1440 <= tzo <= 1440;
currently only - 840 to + 840 are needed */
2002-05-03 11:29:38 +04:00
} ;
/* Duration value */
typedef struct _xmlSchemaValDuration xmlSchemaValDuration ;
typedef xmlSchemaValDuration * xmlSchemaValDurationPtr ;
struct _xmlSchemaValDuration {
long mon ; /* mon stores years also */
2012-09-11 09:26:36 +04:00
long day ;
2002-05-03 11:29:38 +04:00
double sec ; /* sec stores min and hour also */
} ;
2002-04-16 19:50:10 +04:00
typedef struct _xmlSchemaValDecimal xmlSchemaValDecimal ;
typedef xmlSchemaValDecimal * xmlSchemaValDecimalPtr ;
2023-11-07 23:08:01 +03:00
struct _xmlSchemaValDecimal
{
xmlChar * str ;
unsigned integralPlaces ;
unsigned fractionalPlaces ;
2002-04-16 19:50:10 +04:00
} ;
2003-03-31 01:10:09 +04:00
typedef struct _xmlSchemaValQName xmlSchemaValQName ;
typedef xmlSchemaValQName * xmlSchemaValQNamePtr ;
struct _xmlSchemaValQName {
xmlChar * name ;
xmlChar * uri ;
} ;
2003-08-08 18:00:28 +04:00
typedef struct _xmlSchemaValHex xmlSchemaValHex ;
typedef xmlSchemaValHex * xmlSchemaValHexPtr ;
struct _xmlSchemaValHex {
xmlChar * str ;
unsigned int total ;
} ;
2003-08-27 18:15:15 +04:00
typedef struct _xmlSchemaValBase64 xmlSchemaValBase64 ;
typedef xmlSchemaValBase64 * xmlSchemaValBase64Ptr ;
struct _xmlSchemaValBase64 {
xmlChar * str ;
unsigned int total ;
} ;
2002-04-16 19:50:10 +04:00
struct _xmlSchemaVal {
xmlSchemaValType type ;
2005-06-09 14:32:53 +04:00
struct _xmlSchemaVal * next ;
2002-04-16 19:50:10 +04:00
union {
2002-05-22 10:40:27 +04:00
xmlSchemaValDecimal decimal ;
2002-05-03 11:29:38 +04:00
xmlSchemaValDate date ;
xmlSchemaValDuration dur ;
2003-03-31 01:10:09 +04:00
xmlSchemaValQName qname ;
2003-08-08 18:00:28 +04:00
xmlSchemaValHex hex ;
2003-08-27 18:15:15 +04:00
xmlSchemaValBase64 base64 ;
2002-09-16 14:51:38 +04:00
float f ;
double d ;
2003-02-07 02:41:59 +03:00
int b ;
2003-03-29 13:53:38 +03:00
xmlChar * str ;
2002-04-16 19:50:10 +04:00
} value ;
} ;
static int xmlSchemaTypesInitialized = 0 ;
2024-06-16 00:53:04 +03:00
static double xmlSchemaNAN = 0.0 ;
static double xmlSchemaPINF = 0.0 ;
static double xmlSchemaNINF = 0.0 ;
2002-04-16 19:50:10 +04:00
static xmlHashTablePtr xmlSchemaTypesBank = NULL ;
2003-01-27 15:35:42 +03:00
/*
* Basic types
*/
2002-04-16 19:50:10 +04:00
static xmlSchemaTypePtr xmlSchemaTypeStringDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeAnyTypeDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeAnySimpleTypeDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeDecimalDef = NULL ;
2002-05-03 11:29:38 +04:00
static xmlSchemaTypePtr xmlSchemaTypeDatetimeDef = NULL ;
2002-04-16 19:50:10 +04:00
static xmlSchemaTypePtr xmlSchemaTypeDateDef = NULL ;
2002-05-03 11:29:38 +04:00
static xmlSchemaTypePtr xmlSchemaTypeTimeDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGYearDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGYearMonthDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGDayDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGMonthDayDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeGMonthDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeDurationDef = NULL ;
2002-09-16 14:51:38 +04:00
static xmlSchemaTypePtr xmlSchemaTypeFloatDef = NULL ;
2003-02-07 02:41:59 +03:00
static xmlSchemaTypePtr xmlSchemaTypeBooleanDef = NULL ;
2002-09-16 14:51:38 +04:00
static xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL ;
2003-07-07 01:13:49 +04:00
static xmlSchemaTypePtr xmlSchemaTypeHexBinaryDef = NULL ;
2003-08-27 18:15:15 +04:00
static xmlSchemaTypePtr xmlSchemaTypeBase64BinaryDef = NULL ;
2003-02-04 17:43:39 +03:00
static xmlSchemaTypePtr xmlSchemaTypeAnyURIDef = NULL ;
2002-04-16 19:50:10 +04:00
2003-01-27 15:35:42 +03:00
/*
* Derived types
*/
static xmlSchemaTypePtr xmlSchemaTypePositiveIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNonPositiveIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNegativeIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNonNegativeIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeIntegerDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeLongDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeIntDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeShortDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeByteDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeUnsignedLongDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeUnsignedIntDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeUnsignedShortDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeUnsignedByteDef = NULL ;
2003-02-27 20:42:22 +03:00
static xmlSchemaTypePtr xmlSchemaTypeNormStringDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeTokenDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeLanguageDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNameDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeQNameDef = NULL ;
2003-02-04 17:43:39 +03:00
static xmlSchemaTypePtr xmlSchemaTypeNCNameDef = NULL ;
2003-02-27 20:42:22 +03:00
static xmlSchemaTypePtr xmlSchemaTypeIdDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeIdrefDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeIdrefsDef = NULL ;
2003-03-18 19:53:17 +03:00
static xmlSchemaTypePtr xmlSchemaTypeEntityDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeEntitiesDef = NULL ;
2003-03-31 01:10:09 +04:00
static xmlSchemaTypePtr xmlSchemaTypeNotationDef = NULL ;
2003-02-27 20:42:22 +03:00
static xmlSchemaTypePtr xmlSchemaTypeNmtokenDef = NULL ;
static xmlSchemaTypePtr xmlSchemaTypeNmtokensDef = NULL ;
2003-01-27 15:35:42 +03:00
2003-10-10 04:49:42 +04:00
/************************************************************************
* *
2012-09-11 09:26:36 +04:00
* Datatype error handlers *
2003-10-10 04:49:42 +04:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSchemaTypeErrMemory :
2020-03-08 19:19:42 +03:00
* @ extra : extra information
2003-10-10 04:49:42 +04:00
*
* Handle an out of memory condition
*/
static void
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( void )
2003-10-10 04:49:42 +04:00
{
2023-12-18 21:51:32 +03:00
xmlRaiseMemoryError ( NULL , NULL , NULL , XML_FROM_DATATYPE , NULL ) ;
2003-10-10 04:49:42 +04:00
}
/************************************************************************
* *
2012-09-11 09:26:36 +04:00
* Base types support *
2003-10-10 04:49:42 +04:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-09 14:32:53 +04:00
/**
* xmlSchemaNewValue :
* @ type : the value type
*
* Allocate a new simple type value
*
* Returns a pointer to the new value or NULL in case of error
*/
static xmlSchemaValPtr
xmlSchemaNewValue ( xmlSchemaValType type ) {
xmlSchemaValPtr value ;
value = ( xmlSchemaValPtr ) xmlMalloc ( sizeof ( xmlSchemaVal ) ) ;
if ( value = = NULL ) {
return ( NULL ) ;
}
memset ( value , 0 , sizeof ( xmlSchemaVal ) ) ;
value - > type = type ;
return ( value ) ;
}
static xmlSchemaFacetPtr
xmlSchemaNewMinLengthFacet ( int value )
{
xmlSchemaFacetPtr ret ;
2023-11-07 23:08:01 +03:00
size_t bufsize ;
xmlSchemaValDecimal * decimal ;
2005-06-09 14:32:53 +04:00
ret = xmlSchemaNewFacet ( ) ;
2006-03-09 21:41:40 +03:00
if ( ret = = NULL ) {
return ( NULL ) ;
}
2005-06-09 14:32:53 +04:00
ret - > type = XML_SCHEMA_FACET_MINLENGTH ;
ret - > val = xmlSchemaNewValue ( XML_SCHEMAS_NNINTEGER ) ;
2013-07-22 10:28:20 +04:00
if ( ret - > val = = NULL ) {
xmlFree ( ret ) ;
2023-11-07 23:08:01 +03:00
return ( NULL ) ;
2013-07-22 10:28:20 +04:00
}
2023-11-07 23:08:01 +03:00
bufsize = snprintf ( NULL , 0 , " %+d.0 " , value ) + 1 ;
decimal = & ret - > val - > value . decimal ;
decimal - > str = xmlMalloc ( bufsize ) ;
if ( decimal - > str = = NULL )
{
xmlSchemaFreeFacet ( ret ) ;
return NULL ;
}
snprintf ( ( char * ) decimal - > str , bufsize , " %+d.0 " , value ) ;
decimal - > integralPlaces = bufsize - 4 ;
decimal - > fractionalPlaces = 1 ;
2005-06-09 14:32:53 +04:00
return ( ret ) ;
}
2002-04-16 19:50:10 +04:00
/*
* xmlSchemaInitBasicType :
* @ name : the type name
2003-02-27 20:42:22 +03:00
* @ type : the value type associated
2002-04-16 19:50:10 +04:00
*
2004-06-29 21:04:39 +04:00
* Initialize one primitive built - in type
2002-04-16 19:50:10 +04:00
*/
static xmlSchemaTypePtr
2012-09-11 09:26:36 +04:00
xmlSchemaInitBasicType ( const char * name , xmlSchemaValType type ,
2004-06-29 21:04:39 +04:00
xmlSchemaTypePtr baseType ) {
2002-04-16 19:50:10 +04:00
xmlSchemaTypePtr ret ;
ret = ( xmlSchemaTypePtr ) xmlMalloc ( sizeof ( xmlSchemaType ) ) ;
if ( ret = = NULL ) {
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( ) ;
2002-04-16 19:50:10 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaType ) ) ;
2003-11-22 23:37:51 +03:00
ret - > name = ( const xmlChar * ) name ;
2005-06-09 14:32:53 +04:00
ret - > targetNamespace = XML_SCHEMAS_NAMESPACE_NAME ;
2002-04-16 19:50:10 +04:00
ret - > type = XML_SCHEMA_TYPE_BASIC ;
2012-09-11 09:26:36 +04:00
ret - > baseType = baseType ;
2005-06-09 14:32:53 +04:00
ret - > contentType = XML_SCHEMA_CONTENT_BASIC ;
2004-06-29 21:04:39 +04:00
/*
2005-06-09 14:32:53 +04:00
* Primitive types .
2004-06-29 21:04:39 +04:00
*/
2012-09-11 09:26:36 +04:00
switch ( type ) {
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_DECIMAL :
case XML_SCHEMAS_DATE :
case XML_SCHEMAS_DATETIME :
case XML_SCHEMAS_TIME :
case XML_SCHEMAS_GYEAR :
case XML_SCHEMAS_GYEARMONTH :
case XML_SCHEMAS_GMONTH :
case XML_SCHEMAS_GMONTHDAY :
case XML_SCHEMAS_GDAY :
case XML_SCHEMAS_DURATION :
case XML_SCHEMAS_FLOAT :
case XML_SCHEMAS_DOUBLE :
case XML_SCHEMAS_BOOLEAN :
case XML_SCHEMAS_ANYURI :
case XML_SCHEMAS_HEXBINARY :
case XML_SCHEMAS_BASE64BINARY :
case XML_SCHEMAS_QNAME :
case XML_SCHEMAS_NOTATION :
2004-06-29 21:04:39 +04:00
ret - > flags | = XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE ;
2005-06-09 14:32:53 +04:00
break ;
2004-06-30 15:48:47 +04:00
default :
2005-06-09 14:32:53 +04:00
break ;
}
/*
* Set variety .
*/
switch ( type ) {
case XML_SCHEMAS_ANYTYPE :
case XML_SCHEMAS_ANYSIMPLETYPE :
break ;
case XML_SCHEMAS_IDREFS :
case XML_SCHEMAS_NMTOKENS :
case XML_SCHEMAS_ENTITIES :
ret - > flags | = XML_SCHEMAS_TYPE_VARIETY_LIST ;
ret - > facets = xmlSchemaNewMinLengthFacet ( 1 ) ;
2012-09-11 09:26:36 +04:00
ret - > flags | = XML_SCHEMAS_TYPE_HAS_FACETS ;
2005-06-09 14:32:53 +04:00
break ;
default :
ret - > flags | = XML_SCHEMAS_TYPE_VARIETY_ATOMIC ;
break ;
2004-06-29 21:04:39 +04:00
}
2002-04-16 19:50:10 +04:00
xmlHashAddEntry2 ( xmlSchemaTypesBank , ret - > name ,
XML_SCHEMAS_NAMESPACE_NAME , ret ) ;
2004-06-29 21:04:39 +04:00
ret - > builtInType = type ;
2002-04-16 19:50:10 +04:00
return ( ret ) ;
}
2023-11-07 23:08:01 +03:00
static const xmlChar *
xmlSchemaValDecimalGetFractionalPart ( const xmlSchemaValDecimal * decimal )
{
/* 2 = sign+dot */
return decimal - > str + 2 + decimal - > integralPlaces ;
}
static int
xmlSchemaValDecimalIsInteger ( const xmlSchemaValDecimal * decimal )
{
return decimal - > fractionalPlaces = = 1 & & xmlSchemaValDecimalGetFractionalPart ( decimal ) [ 0 ] = = ' 0 ' ;
}
static unsigned long
xmlSchemaValDecimalGetSignificantDigitCount ( const xmlSchemaValDecimal * decimal )
{
unsigned fractionalPlaces = xmlSchemaValDecimalIsInteger ( decimal ) ? 0 : decimal - > fractionalPlaces ;
unsigned integralPlaces = decimal - > integralPlaces ;
if ( integralPlaces = = 1 & & decimal - > str [ 1 ] = = ' 0 ' )
{
integralPlaces = 0 ;
}
if ( integralPlaces + fractionalPlaces = = 0 )
{
/* 0, but that's still 1 significant digit */
return 1 ;
}
return integralPlaces + fractionalPlaces ;
}
/**
* @ brief Compares two decimals
*
* @ param lhs
* @ param rhs
* @ return positive value if lhs > rhs , negative if lhs < rhs , or 0 if lhs = = rhs
*/
static int xmlSchemaValDecimalCompare ( const xmlSchemaValDecimal * lhs , const xmlSchemaValDecimal * rhs )
{
int sign = 1 ;
/* may be +0 and -0 for some reason, handle */
if ( strcmp ( ( const char * ) lhs - > str + 1 , " 0.0 " ) = = 0 & &
strcmp ( ( const char * ) rhs - > str + 1 , " 0.0 " ) = = 0 )
{
return 0 ;
}
/* first take care of sign */
if ( lhs - > str [ 0 ] ! = rhs - > str [ 0 ] )
{
/* ASCII- > ASCII+ */
return rhs - > str [ 0 ] - lhs - > str [ 0 ] ;
}
/* signs are equal, but if negative the comparison must be reversed */
if ( lhs - > str [ 0 ] = = ' - ' )
{
sign = - 1 ;
}
/* internal representation never contains leading zeroes, longer decimal representation = larger number */
if ( lhs - > integralPlaces ! = rhs - > integralPlaces )
{
return ( ( int ) lhs - > integralPlaces - ( int ) rhs - > integralPlaces ) * sign ;
}
/* same length, only digits => lexicographical sorting == numerical sorting.
If integral parts are equal it will compare compare fractional parts . Again , lexicographical is good enough ,
length doesn ' t matter . We ' ll be starting from 0.1 , always comparing like to like , and NULL < ' 0 '
If one is shorter and is equal until end , it must be smaller , since there are no trailing zeroes
and the longer number must therefore have at least one non - zero digit after the other has ended .
+ 1 to skip the sign
*/
return strcmp ( ( const char * ) lhs - > str + 1 , ( const char * ) rhs - > str + 1 ) * sign ;
}
static int xmlSchemaValDecimalCompareWithInteger ( const xmlSchemaValDecimal * lhs , long rhs )
{
/* can handle integers up to 128 bits, should be good for a while */
char buf [ 43 ] ;
xmlSchemaValDecimal tmpVal ;
/* 3 = sign+dot+0+NULL */
tmpVal . integralPlaces = snprintf ( buf , sizeof ( buf ) , " %+ld.0 " , rhs ) - 3 ;
tmpVal . str = ( xmlChar * ) buf ;
tmpVal . fractionalPlaces = 1 ;
return xmlSchemaValDecimalCompare ( lhs , & tmpVal ) ;
}
2005-07-28 04:50:22 +04:00
/*
* WARNING : Those type reside normally in xmlschemas . c but are
* redefined here locally in oder of being able to use them for xs : anyType -
* TODO : Remove those definition if we move the types to a header file .
* TODO : Always keep those structs up - to - date with the originals .
*/
# define UNBOUNDED (1 << 30)
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem ;
typedef xmlSchemaTreeItem * xmlSchemaTreeItemPtr ;
struct _xmlSchemaTreeItem {
xmlSchemaTypeType type ;
xmlSchemaAnnotPtr annot ;
xmlSchemaTreeItemPtr next ;
xmlSchemaTreeItemPtr children ;
} ;
typedef struct _xmlSchemaParticle xmlSchemaParticle ;
typedef xmlSchemaParticle * xmlSchemaParticlePtr ;
struct _xmlSchemaParticle {
xmlSchemaTypeType type ;
xmlSchemaAnnotPtr annot ;
xmlSchemaTreeItemPtr next ;
xmlSchemaTreeItemPtr children ;
int minOccurs ;
int maxOccurs ;
xmlNodePtr node ;
} ;
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup ;
typedef xmlSchemaModelGroup * xmlSchemaModelGroupPtr ;
struct _xmlSchemaModelGroup {
xmlSchemaTypeType type ;
xmlSchemaAnnotPtr annot ;
xmlSchemaTreeItemPtr next ;
xmlSchemaTreeItemPtr children ;
xmlNodePtr node ;
} ;
static xmlSchemaParticlePtr
xmlSchemaAddParticle ( void )
{
xmlSchemaParticlePtr ret = NULL ;
ret = ( xmlSchemaParticlePtr )
xmlMalloc ( sizeof ( xmlSchemaParticle ) ) ;
if ( ret = = NULL ) {
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( ) ;
2005-07-28 04:50:22 +04:00
return ( NULL ) ;
}
memset ( ret , 0 , sizeof ( xmlSchemaParticle ) ) ;
ret - > type = XML_SCHEMA_TYPE_PARTICLE ;
ret - > minOccurs = 1 ;
ret - > maxOccurs = 1 ;
return ( ret ) ;
}
2023-03-14 15:55:06 +03:00
static void
xmlSchemaFreeTypeEntry ( void * type , const xmlChar * name ATTRIBUTE_UNUSED ) {
xmlSchemaFreeType ( ( xmlSchemaTypePtr ) type ) ;
}
/**
* xmlSchemaCleanupTypesInternal :
*
* Cleanup the default XML Schemas type library
*/
static void
xmlSchemaCleanupTypesInternal ( void ) {
xmlSchemaParticlePtr particle ;
/*
* Free xs : anyType .
*/
if ( xmlSchemaTypeAnyTypeDef ! = NULL ) {
/* Attribute wildcard. */
xmlSchemaFreeWildcard ( xmlSchemaTypeAnyTypeDef - > attributeWildcard ) ;
/* Content type. */
particle = ( xmlSchemaParticlePtr ) xmlSchemaTypeAnyTypeDef - > subtypes ;
/* Wildcard. */
xmlSchemaFreeWildcard ( ( xmlSchemaWildcardPtr )
particle - > children - > children - > children ) ;
xmlFree ( ( xmlSchemaParticlePtr ) particle - > children - > children ) ;
/* Sequence model group. */
xmlFree ( ( xmlSchemaModelGroupPtr ) particle - > children ) ;
xmlFree ( ( xmlSchemaParticlePtr ) particle ) ;
xmlSchemaTypeAnyTypeDef - > subtypes = NULL ;
xmlSchemaTypeAnyTypeDef = NULL ;
}
xmlHashFree ( xmlSchemaTypesBank , xmlSchemaFreeTypeEntry ) ;
xmlSchemaTypesBank = NULL ;
/* Note that the xmlSchemaType*Def pointers aren't set to NULL. */
}
2002-04-16 19:50:10 +04:00
/*
* xmlSchemaInitTypes :
*
* Initialize the default XML Schemas type library
2023-03-14 15:55:06 +03:00
*
* Returns 0 on success , - 1 on error .
2002-04-16 19:50:10 +04:00
*/
2023-03-14 15:55:06 +03:00
int
2003-03-28 00:25:38 +03:00
xmlSchemaInitTypes ( void )
{
2002-04-16 19:50:10 +04:00
if ( xmlSchemaTypesInitialized ! = 0 )
2023-03-14 15:55:06 +03:00
return ( 0 ) ;
2024-06-16 00:53:04 +03:00
# if defined(NAN) && defined(INFINITY)
xmlSchemaNAN = NAN ;
xmlSchemaPINF = INFINITY ;
xmlSchemaNINF = - INFINITY ;
# else
/* MSVC doesn't allow division by zero in constant expressions. */
double zero = 0.0 ;
xmlSchemaNAN = 0.0 / zero ;
xmlSchemaPINF = 1.0 / zero ;
xmlSchemaNINF = - xmlSchemaPINF ;
# endif
2002-04-16 19:50:10 +04:00
xmlSchemaTypesBank = xmlHashCreate ( 40 ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypesBank = = NULL ) {
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( ) ;
2023-03-14 15:55:06 +03:00
goto error ;
}
2012-09-11 09:26:36 +04:00
2003-01-27 15:35:42 +03:00
/*
2004-06-29 21:04:39 +04:00
* 3.4 .7 Built - in Complex Type Definition
*/
2003-02-27 20:42:22 +03:00
xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType ( " anyType " ,
2012-09-11 09:26:36 +04:00
XML_SCHEMAS_ANYTYPE ,
2004-06-29 21:04:39 +04:00
NULL ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeAnyTypeDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeAnyTypeDef - > baseType = xmlSchemaTypeAnyTypeDef ;
xmlSchemaTypeAnyTypeDef - > contentType = XML_SCHEMA_CONTENT_MIXED ;
2005-07-28 04:50:22 +04:00
/*
* Init the content type .
*/
2012-09-11 09:26:36 +04:00
xmlSchemaTypeAnyTypeDef - > contentType = XML_SCHEMA_CONTENT_MIXED ;
2004-06-29 21:04:39 +04:00
{
2005-07-28 04:50:22 +04:00
xmlSchemaParticlePtr particle ;
xmlSchemaModelGroupPtr sequence ;
2004-06-29 21:04:39 +04:00
xmlSchemaWildcardPtr wild ;
2005-07-28 04:50:22 +04:00
/* First particle. */
particle = xmlSchemaAddParticle ( ) ;
if ( particle = = NULL )
2023-03-14 15:55:06 +03:00
goto error ;
2005-07-28 04:50:22 +04:00
xmlSchemaTypeAnyTypeDef - > subtypes = ( xmlSchemaTypePtr ) particle ;
/* Sequence model group. */
sequence = ( xmlSchemaModelGroupPtr )
xmlMalloc ( sizeof ( xmlSchemaModelGroup ) ) ;
if ( sequence = = NULL ) {
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( ) ;
2023-03-14 15:55:06 +03:00
goto error ;
2005-07-28 04:50:22 +04:00
}
memset ( sequence , 0 , sizeof ( xmlSchemaModelGroup ) ) ;
2012-09-11 09:26:36 +04:00
sequence - > type = XML_SCHEMA_TYPE_SEQUENCE ;
2005-07-28 04:50:22 +04:00
particle - > children = ( xmlSchemaTreeItemPtr ) sequence ;
/* Second particle. */
particle = xmlSchemaAddParticle ( ) ;
if ( particle = = NULL )
2023-03-14 15:55:06 +03:00
goto error ;
2005-07-28 04:50:22 +04:00
particle - > minOccurs = 0 ;
particle - > maxOccurs = UNBOUNDED ;
sequence - > children = ( xmlSchemaTreeItemPtr ) particle ;
/* The wildcard */
wild = ( xmlSchemaWildcardPtr ) xmlMalloc ( sizeof ( xmlSchemaWildcard ) ) ;
if ( wild = = NULL ) {
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( ) ;
2023-03-14 15:55:06 +03:00
goto error ;
2005-07-28 04:50:22 +04:00
}
memset ( wild , 0 , sizeof ( xmlSchemaWildcard ) ) ;
wild - > type = XML_SCHEMA_TYPE_ANY ;
2012-09-11 09:26:36 +04:00
wild - > any = 1 ;
wild - > processContents = XML_SCHEMAS_ANY_LAX ;
particle - > children = ( xmlSchemaTreeItemPtr ) wild ;
2005-07-28 04:50:22 +04:00
/*
* Create the attribute wildcard .
*/
2004-06-29 21:04:39 +04:00
wild = ( xmlSchemaWildcardPtr ) xmlMalloc ( sizeof ( xmlSchemaWildcard ) ) ;
if ( wild = = NULL ) {
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( ) ;
2023-03-14 15:55:06 +03:00
goto error ;
2004-06-29 21:04:39 +04:00
}
memset ( wild , 0 , sizeof ( xmlSchemaWildcard ) ) ;
wild - > any = 1 ;
2012-09-11 09:26:36 +04:00
wild - > processContents = XML_SCHEMAS_ANY_LAX ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeAnyTypeDef - > attributeWildcard = wild ;
}
2012-09-11 09:26:36 +04:00
xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType ( " anySimpleType " ,
modified parsing of <list>, <union>, <restriction>, <sequence>, <choice>,
* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
<sequence>, <choice>, <include>, <import>.
Fixed schema defaults (elementFormDefault, etc.) for included
schemas.
Fixed a bug which reported attributes as invalid on
elements declarations with the built-in type 'anyType'.
Added "lax" validation of the content of elements of type
'anyType'.
Fixed: element declarations with the same name were treated
as duplicate if located in the subtree of <choice> -> <sequence>.
(This was bug 150623, submitted by Roland Lezuo)
Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
by Igor Kapitanker. (This was bug 150647, submitted by Igor
Kapitanker)
* xmlschemastypes.c: Changed the type of anyType to
XML_SCHEMAS_ANYTYPE.
* include/libxml/xmlerror.h: Added schema parser errors.
* result/schemas/bug145246_0_0*
result/schemas/extension1_0_2.err: Changed test results.
* result/schemas/ct-sc-nobase_0_0*
result/schemas/facet-whiteSpace_0_0*
result/schemas/import1_0_0* result/schemas/import2_0_0*
result/schemas/include2_0_0* result/schemas/include3_0_0*
result/schemas/restriction-attr1_0_0*
result/schemas/seq-dubl-elem1_0_0*
result/schemas/xsd-list-itemType_0_0*: Added new rest results.
test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
test/schemas/import2_0* test/schemas/include2_0*
test/schemas/include3_0* test/schemas/restriction-attr1_0*
test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
test/schemas/xsd-list-itemType_0*: Added new tests and missing
files.
2004-08-21 03:09:47 +04:00
XML_SCHEMAS_ANYSIMPLETYPE ,
2004-06-29 21:04:39 +04:00
xmlSchemaTypeAnyTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeAnySimpleTypeDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
/*
* primitive datatypes
*/
xmlSchemaTypeStringDef = xmlSchemaInitBasicType ( " string " ,
XML_SCHEMAS_STRING ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeStringDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType ( " decimal " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_DECIMAL ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeDecimalDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeDateDef = xmlSchemaInitBasicType ( " date " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_DATE ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeDateDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType ( " dateTime " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_DATETIME ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeDatetimeDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeTimeDef = xmlSchemaInitBasicType ( " time " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_TIME ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeTimeDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeGYearDef = xmlSchemaInitBasicType ( " gYear " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_GYEAR ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeGYearDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType ( " gYearMonth " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_GYEARMONTH ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeGYearMonthDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType ( " gMonth " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_GMONTH ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeGMonthDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType ( " gMonthDay " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_GMONTHDAY ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeGMonthDayDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeGDayDef = xmlSchemaInitBasicType ( " gDay " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_GDAY ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeGDayDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeDurationDef = xmlSchemaInitBasicType ( " duration " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_DURATION ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeDurationDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeFloatDef = xmlSchemaInitBasicType ( " float " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_FLOAT ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeFloatDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType ( " double " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_DOUBLE ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeDoubleDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeBooleanDef = xmlSchemaInitBasicType ( " boolean " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_BOOLEAN ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeBooleanDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeAnyURIDef = xmlSchemaInitBasicType ( " anyURI " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_ANYURI ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeAnyURIDef = = NULL )
goto error ;
2003-07-07 01:13:49 +04:00
xmlSchemaTypeHexBinaryDef = xmlSchemaInitBasicType ( " hexBinary " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_HEXBINARY ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeHexBinaryDef = = NULL )
goto error ;
2003-08-27 18:15:15 +04:00
xmlSchemaTypeBase64BinaryDef
2004-06-29 21:04:39 +04:00
= xmlSchemaInitBasicType ( " base64Binary " , XML_SCHEMAS_BASE64BINARY ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeBase64BinaryDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeNotationDef = xmlSchemaInitBasicType ( " NOTATION " ,
XML_SCHEMAS_NOTATION ,
2012-09-11 09:26:36 +04:00
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNotationDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeQNameDef = xmlSchemaInitBasicType ( " QName " ,
XML_SCHEMAS_QNAME ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeQNameDef = = NULL )
goto error ;
2002-04-16 19:50:10 +04:00
2003-01-27 15:35:42 +03:00
/*
* derived datatypes
*/
2003-02-27 20:42:22 +03:00
xmlSchemaTypeIntegerDef = xmlSchemaInitBasicType ( " integer " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_INTEGER ,
xmlSchemaTypeDecimalDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeIntegerDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypeNonPositiveIntegerDef =
xmlSchemaInitBasicType ( " nonPositiveInteger " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_NPINTEGER ,
xmlSchemaTypeIntegerDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNonPositiveIntegerDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypeNegativeIntegerDef =
2004-06-29 21:04:39 +04:00
xmlSchemaInitBasicType ( " negativeInteger " , XML_SCHEMAS_NINTEGER ,
xmlSchemaTypeNonPositiveIntegerDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNegativeIntegerDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypeLongDef =
2004-06-29 21:04:39 +04:00
xmlSchemaInitBasicType ( " long " , XML_SCHEMAS_LONG ,
xmlSchemaTypeIntegerDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeLongDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeIntDef = xmlSchemaInitBasicType ( " int " , XML_SCHEMAS_INT ,
xmlSchemaTypeLongDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeIntDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeShortDef = xmlSchemaInitBasicType ( " short " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_SHORT ,
xmlSchemaTypeIntDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeShortDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeByteDef = xmlSchemaInitBasicType ( " byte " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_BYTE ,
xmlSchemaTypeShortDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeByteDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypeNonNegativeIntegerDef =
xmlSchemaInitBasicType ( " nonNegativeInteger " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_NNINTEGER ,
xmlSchemaTypeIntegerDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNonNegativeIntegerDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypeUnsignedLongDef =
2004-06-29 21:04:39 +04:00
xmlSchemaInitBasicType ( " unsignedLong " , XML_SCHEMAS_ULONG ,
xmlSchemaTypeNonNegativeIntegerDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeUnsignedLongDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypeUnsignedIntDef =
2004-06-29 21:04:39 +04:00
xmlSchemaInitBasicType ( " unsignedInt " , XML_SCHEMAS_UINT ,
xmlSchemaTypeUnsignedLongDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeUnsignedIntDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypeUnsignedShortDef =
2004-06-29 21:04:39 +04:00
xmlSchemaInitBasicType ( " unsignedShort " , XML_SCHEMAS_USHORT ,
xmlSchemaTypeUnsignedIntDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeUnsignedShortDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypeUnsignedByteDef =
2004-06-29 21:04:39 +04:00
xmlSchemaInitBasicType ( " unsignedByte " , XML_SCHEMAS_UBYTE ,
xmlSchemaTypeUnsignedShortDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeUnsignedByteDef = = NULL )
goto error ;
2003-03-28 00:25:38 +03:00
xmlSchemaTypePositiveIntegerDef =
2004-06-29 21:04:39 +04:00
xmlSchemaInitBasicType ( " positiveInteger " , XML_SCHEMAS_PINTEGER ,
xmlSchemaTypeNonNegativeIntegerDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypePositiveIntegerDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeNormStringDef = xmlSchemaInitBasicType ( " normalizedString " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_NORMSTRING ,
xmlSchemaTypeStringDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNormStringDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeTokenDef = xmlSchemaInitBasicType ( " token " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_TOKEN ,
xmlSchemaTypeNormStringDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeTokenDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeLanguageDef = xmlSchemaInitBasicType ( " language " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_LANGUAGE ,
xmlSchemaTypeTokenDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeLanguageDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeNameDef = xmlSchemaInitBasicType ( " Name " ,
XML_SCHEMAS_NAME ,
xmlSchemaTypeTokenDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNameDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeNmtokenDef = xmlSchemaInitBasicType ( " NMTOKEN " ,
XML_SCHEMAS_NMTOKEN ,
2005-06-09 14:32:53 +04:00
xmlSchemaTypeTokenDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNmtokenDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeNCNameDef = xmlSchemaInitBasicType ( " NCName " ,
XML_SCHEMAS_NCNAME ,
xmlSchemaTypeNameDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNCNameDef = = NULL )
goto error ;
2004-06-29 21:04:39 +04:00
xmlSchemaTypeIdDef = xmlSchemaInitBasicType ( " ID " , XML_SCHEMAS_ID ,
2005-06-09 14:32:53 +04:00
xmlSchemaTypeNCNameDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeIdDef = = NULL )
goto error ;
2003-02-27 20:42:22 +03:00
xmlSchemaTypeIdrefDef = xmlSchemaInitBasicType ( " IDREF " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_IDREF ,
2012-09-11 09:26:36 +04:00
xmlSchemaTypeNCNameDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeIdrefDef = = NULL )
goto error ;
2003-03-18 19:53:17 +03:00
xmlSchemaTypeEntityDef = xmlSchemaInitBasicType ( " ENTITY " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_ENTITY ,
xmlSchemaTypeNCNameDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeEntityDef = = NULL )
goto error ;
2005-06-09 14:32:53 +04:00
/*
* Derived list types .
*/
/* ENTITIES */
2003-03-18 19:53:17 +03:00
xmlSchemaTypeEntitiesDef = xmlSchemaInitBasicType ( " ENTITIES " ,
2004-06-29 21:04:39 +04:00
XML_SCHEMAS_ENTITIES ,
2005-06-09 14:32:53 +04:00
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeEntitiesDef = = NULL )
goto error ;
2005-06-09 14:32:53 +04:00
xmlSchemaTypeEntitiesDef - > subtypes = xmlSchemaTypeEntityDef ;
/* IDREFS */
xmlSchemaTypeIdrefsDef = xmlSchemaInitBasicType ( " IDREFS " ,
XML_SCHEMAS_IDREFS ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeIdrefsDef = = NULL )
goto error ;
2005-06-09 14:32:53 +04:00
xmlSchemaTypeIdrefsDef - > subtypes = xmlSchemaTypeIdrefDef ;
/* NMTOKENS */
xmlSchemaTypeNmtokensDef = xmlSchemaInitBasicType ( " NMTOKENS " ,
XML_SCHEMAS_NMTOKENS ,
xmlSchemaTypeAnySimpleTypeDef ) ;
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypeNmtokensDef = = NULL )
goto error ;
2005-06-09 14:32:53 +04:00
xmlSchemaTypeNmtokensDef - > subtypes = xmlSchemaTypeNmtokenDef ;
2002-04-16 19:50:10 +04:00
xmlSchemaTypesInitialized = 1 ;
2023-03-14 15:55:06 +03:00
return ( 0 ) ;
2002-04-16 19:50:10 +04:00
2023-03-14 15:55:06 +03:00
error :
xmlSchemaCleanupTypesInternal ( ) ;
return ( - 1 ) ;
2017-11-09 18:42:47 +03:00
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaCleanupTypes :
*
2022-03-06 15:55:48 +03:00
* DEPRECATED : This function will be made private . Call xmlCleanupParser
* to free global state but see the warnings there . xmlCleanupParser
* should be only called once at program exit . In most cases , you don ' t
2023-03-14 15:55:06 +03:00
* have to call cleanup functions at all .
2022-03-06 15:55:48 +03:00
*
2002-04-16 19:50:10 +04:00
* Cleanup the default XML Schemas type library
*/
2012-09-11 09:26:36 +04:00
void
2002-04-16 19:50:10 +04:00
xmlSchemaCleanupTypes ( void ) {
2023-03-14 15:55:06 +03:00
if ( xmlSchemaTypesInitialized ! = 0 ) {
xmlSchemaCleanupTypesInternal ( ) ;
xmlSchemaTypesInitialized = 0 ;
2005-07-28 04:50:22 +04:00
}
2002-04-16 19:50:10 +04:00
}
2004-06-29 21:04:39 +04:00
/**
2004-10-27 21:29:04 +04:00
* xmlSchemaIsBuiltInTypeFacet :
2004-06-29 21:04:39 +04:00
* @ type : the built - in type
* @ facetType : the facet type
*
* Evaluates if a specific facet can be
* used in conjunction with a type .
*
* Returns 1 if the facet can be used with the given built - in type ,
* 0 otherwise and - 1 in case the type is not a built - in type .
*/
int
xmlSchemaIsBuiltInTypeFacet ( xmlSchemaTypePtr type , int facetType )
{
2004-11-05 20:22:25 +03:00
if ( type = = NULL )
return ( - 1 ) ;
2004-06-29 21:04:39 +04:00
if ( type - > type ! = XML_SCHEMA_TYPE_BASIC )
return ( - 1 ) ;
switch ( type - > builtInType ) {
case XML_SCHEMAS_BOOLEAN :
if ( ( facetType = = XML_SCHEMA_FACET_PATTERN ) | |
( facetType = = XML_SCHEMA_FACET_WHITESPACE ) )
return ( 1 ) ;
else
2012-09-11 09:26:36 +04:00
return ( 0 ) ;
2004-06-29 21:04:39 +04:00
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_NOTATION :
case XML_SCHEMAS_QNAME :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_ANYURI :
case XML_SCHEMAS_BASE64BINARY :
2004-06-29 21:04:39 +04:00
case XML_SCHEMAS_HEXBINARY :
if ( ( facetType = = XML_SCHEMA_FACET_LENGTH ) | |
( facetType = = XML_SCHEMA_FACET_MINLENGTH ) | |
( facetType = = XML_SCHEMA_FACET_MAXLENGTH ) | |
( facetType = = XML_SCHEMA_FACET_PATTERN ) | |
( facetType = = XML_SCHEMA_FACET_ENUMERATION ) | |
( facetType = = XML_SCHEMA_FACET_WHITESPACE ) )
return ( 1 ) ;
else
return ( 0 ) ;
case XML_SCHEMAS_DECIMAL :
if ( ( facetType = = XML_SCHEMA_FACET_TOTALDIGITS ) | |
( facetType = = XML_SCHEMA_FACET_FRACTIONDIGITS ) | |
( facetType = = XML_SCHEMA_FACET_PATTERN ) | |
( facetType = = XML_SCHEMA_FACET_WHITESPACE ) | |
( facetType = = XML_SCHEMA_FACET_ENUMERATION ) | |
( facetType = = XML_SCHEMA_FACET_MAXINCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MAXEXCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MININCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MINEXCLUSIVE ) )
return ( 1 ) ;
else
2012-09-11 09:26:36 +04:00
return ( 0 ) ;
2004-06-29 21:04:39 +04:00
case XML_SCHEMAS_TIME :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_GDAY :
2004-06-29 21:04:39 +04:00
case XML_SCHEMAS_GMONTH :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_GMONTHDAY :
case XML_SCHEMAS_GYEAR :
2004-06-29 21:04:39 +04:00
case XML_SCHEMAS_GYEARMONTH :
case XML_SCHEMAS_DATE :
case XML_SCHEMAS_DATETIME :
case XML_SCHEMAS_DURATION :
case XML_SCHEMAS_FLOAT :
case XML_SCHEMAS_DOUBLE :
if ( ( facetType = = XML_SCHEMA_FACET_PATTERN ) | |
( facetType = = XML_SCHEMA_FACET_ENUMERATION ) | |
( facetType = = XML_SCHEMA_FACET_WHITESPACE ) | |
( facetType = = XML_SCHEMA_FACET_MAXINCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MAXEXCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MININCLUSIVE ) | |
( facetType = = XML_SCHEMA_FACET_MINEXCLUSIVE ) )
return ( 1 ) ;
else
2012-09-11 09:26:36 +04:00
return ( 0 ) ;
2004-06-29 21:04:39 +04:00
default :
2004-09-28 16:33:52 +04:00
break ;
2004-06-29 21:04:39 +04:00
}
return ( 0 ) ;
}
/**
* xmlSchemaGetBuiltInType :
* @ type : the type of the built in type
*
* Gives you the type struct for a built - in
* type by its type id .
*
* Returns the type if found , NULL otherwise .
*/
xmlSchemaTypePtr
xmlSchemaGetBuiltInType ( xmlSchemaValType type )
{
2023-03-14 15:55:06 +03:00
if ( ( xmlSchemaTypesInitialized = = 0 ) & &
( xmlSchemaInitTypes ( ) < 0 ) )
return ( NULL ) ;
2004-06-29 21:04:39 +04:00
switch ( type ) {
2012-09-11 09:26:36 +04:00
2004-06-29 21:04:39 +04:00
case XML_SCHEMAS_ANYSIMPLETYPE :
return ( xmlSchemaTypeAnySimpleTypeDef ) ;
case XML_SCHEMAS_STRING :
return ( xmlSchemaTypeStringDef ) ;
case XML_SCHEMAS_NORMSTRING :
return ( xmlSchemaTypeNormStringDef ) ;
case XML_SCHEMAS_DECIMAL :
return ( xmlSchemaTypeDecimalDef ) ;
case XML_SCHEMAS_TIME :
return ( xmlSchemaTypeTimeDef ) ;
case XML_SCHEMAS_GDAY :
return ( xmlSchemaTypeGDayDef ) ;
case XML_SCHEMAS_GMONTH :
return ( xmlSchemaTypeGMonthDef ) ;
case XML_SCHEMAS_GMONTHDAY :
2012-09-11 09:26:36 +04:00
return ( xmlSchemaTypeGMonthDayDef ) ;
2004-06-29 21:04:39 +04:00
case XML_SCHEMAS_GYEAR :
return ( xmlSchemaTypeGYearDef ) ;
case XML_SCHEMAS_GYEARMONTH :
return ( xmlSchemaTypeGYearMonthDef ) ;
case XML_SCHEMAS_DATE :
return ( xmlSchemaTypeDateDef ) ;
case XML_SCHEMAS_DATETIME :
return ( xmlSchemaTypeDatetimeDef ) ;
case XML_SCHEMAS_DURATION :
return ( xmlSchemaTypeDurationDef ) ;
case XML_SCHEMAS_FLOAT :
return ( xmlSchemaTypeFloatDef ) ;
case XML_SCHEMAS_DOUBLE :
return ( xmlSchemaTypeDoubleDef ) ;
case XML_SCHEMAS_BOOLEAN :
return ( xmlSchemaTypeBooleanDef ) ;
case XML_SCHEMAS_TOKEN :
return ( xmlSchemaTypeTokenDef ) ;
case XML_SCHEMAS_LANGUAGE :
return ( xmlSchemaTypeLanguageDef ) ;
case XML_SCHEMAS_NMTOKEN :
return ( xmlSchemaTypeNmtokenDef ) ;
case XML_SCHEMAS_NMTOKENS :
return ( xmlSchemaTypeNmtokensDef ) ;
case XML_SCHEMAS_NAME :
return ( xmlSchemaTypeNameDef ) ;
case XML_SCHEMAS_QNAME :
return ( xmlSchemaTypeQNameDef ) ;
case XML_SCHEMAS_NCNAME :
return ( xmlSchemaTypeNCNameDef ) ;
case XML_SCHEMAS_ID :
return ( xmlSchemaTypeIdDef ) ;
case XML_SCHEMAS_IDREF :
return ( xmlSchemaTypeIdrefDef ) ;
case XML_SCHEMAS_IDREFS :
return ( xmlSchemaTypeIdrefsDef ) ;
case XML_SCHEMAS_ENTITY :
return ( xmlSchemaTypeEntityDef ) ;
case XML_SCHEMAS_ENTITIES :
return ( xmlSchemaTypeEntitiesDef ) ;
case XML_SCHEMAS_NOTATION :
return ( xmlSchemaTypeNotationDef ) ;
case XML_SCHEMAS_ANYURI :
return ( xmlSchemaTypeAnyURIDef ) ;
case XML_SCHEMAS_INTEGER :
return ( xmlSchemaTypeIntegerDef ) ;
case XML_SCHEMAS_NPINTEGER :
return ( xmlSchemaTypeNonPositiveIntegerDef ) ;
case XML_SCHEMAS_NINTEGER :
return ( xmlSchemaTypeNegativeIntegerDef ) ;
case XML_SCHEMAS_NNINTEGER :
return ( xmlSchemaTypeNonNegativeIntegerDef ) ;
case XML_SCHEMAS_PINTEGER :
return ( xmlSchemaTypePositiveIntegerDef ) ;
case XML_SCHEMAS_INT :
return ( xmlSchemaTypeIntDef ) ;
case XML_SCHEMAS_UINT :
return ( xmlSchemaTypeUnsignedIntDef ) ;
case XML_SCHEMAS_LONG :
return ( xmlSchemaTypeLongDef ) ;
case XML_SCHEMAS_ULONG :
return ( xmlSchemaTypeUnsignedLongDef ) ;
case XML_SCHEMAS_SHORT :
return ( xmlSchemaTypeShortDef ) ;
case XML_SCHEMAS_USHORT :
return ( xmlSchemaTypeUnsignedShortDef ) ;
case XML_SCHEMAS_BYTE :
return ( xmlSchemaTypeByteDef ) ;
case XML_SCHEMAS_UBYTE :
return ( xmlSchemaTypeUnsignedByteDef ) ;
case XML_SCHEMAS_HEXBINARY :
return ( xmlSchemaTypeHexBinaryDef ) ;
case XML_SCHEMAS_BASE64BINARY :
return ( xmlSchemaTypeBase64BinaryDef ) ;
case XML_SCHEMAS_ANYTYPE :
2012-09-11 09:26:36 +04:00
return ( xmlSchemaTypeAnyTypeDef ) ;
2004-06-29 21:04:39 +04:00
default :
return ( NULL ) ;
}
}
2005-06-15 17:36:10 +04:00
/**
* xmlSchemaValueAppend :
* @ prev : the value
* @ cur : the value to be appended
*
* Appends a next sibling to a list of computed values .
*
* Returns 0 if succeeded and - 1 on API errors .
*/
2005-06-09 14:32:53 +04:00
int
xmlSchemaValueAppend ( xmlSchemaValPtr prev , xmlSchemaValPtr cur ) {
2002-04-16 19:50:10 +04:00
2005-06-09 14:32:53 +04:00
if ( ( prev = = NULL ) | | ( cur = = NULL ) )
return ( - 1 ) ;
prev - > next = cur ;
return ( 0 ) ;
}
2005-06-15 17:36:10 +04:00
/**
* xmlSchemaValueGetNext :
* @ cur : the value
*
* Accessor for the next sibling of a list of computed values .
*
* Returns the next value or NULL if there was none , or on
* API errors .
*/
2005-06-09 14:32:53 +04:00
xmlSchemaValPtr
xmlSchemaValueGetNext ( xmlSchemaValPtr cur ) {
if ( cur = = NULL )
return ( NULL ) ;
return ( cur - > next ) ;
}
2005-06-15 17:36:10 +04:00
/**
* xmlSchemaValueGetAsString :
* @ val : the value
*
* Accessor for the string value of a computed value .
*
* Returns the string value or NULL if there was none , or on
* API errors .
*/
2005-06-09 14:32:53 +04:00
const xmlChar *
xmlSchemaValueGetAsString ( xmlSchemaValPtr val )
2012-09-11 09:26:36 +04:00
{
2005-06-09 14:32:53 +04:00
if ( val = = NULL )
return ( NULL ) ;
switch ( val - > type ) {
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_NORMSTRING :
case XML_SCHEMAS_ANYSIMPLETYPE :
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_ENTITY :
case XML_SCHEMAS_ANYURI :
return ( BAD_CAST val - > value . str ) ;
default :
break ;
2002-04-16 19:50:10 +04:00
}
2005-06-09 14:32:53 +04:00
return ( NULL ) ;
}
2005-06-15 17:36:10 +04:00
/**
* xmlSchemaValueGetAsBoolean :
* @ val : the value
*
* Accessor for the boolean value of a computed value .
*
* Returns 1 if true and 0 if false , or in case of an error . Hmm .
*/
2005-06-09 14:32:53 +04:00
int
xmlSchemaValueGetAsBoolean ( xmlSchemaValPtr val )
2012-09-11 09:26:36 +04:00
{
2005-06-09 14:32:53 +04:00
if ( ( val = = NULL ) | | ( val - > type ! = XML_SCHEMAS_BOOLEAN ) )
return ( 0 ) ;
return ( val - > value . b ) ;
2002-04-16 19:50:10 +04:00
}
2005-02-17 14:10:44 +03:00
/**
* xmlSchemaNewStringValue :
* @ type : the value type
2005-02-19 21:27:14 +03:00
* @ value : the value
2005-02-17 14:10:44 +03:00
*
2012-09-11 09:26:36 +04:00
* Allocate a new simple type value . The type can be
* of XML_SCHEMAS_STRING .
2005-03-07 14:14:14 +03:00
* WARNING : This one is intended to be expanded for other
* string based types . We need this for anySimpleType as well .
2005-06-09 14:32:53 +04:00
* The given value is consumed and freed with the struct .
2005-02-17 14:10:44 +03:00
*
* Returns a pointer to the new value or NULL in case of error
*/
xmlSchemaValPtr
xmlSchemaNewStringValue ( xmlSchemaValType type ,
const xmlChar * value )
{
xmlSchemaValPtr val ;
if ( type ! = XML_SCHEMAS_STRING )
return ( NULL ) ;
val = ( xmlSchemaValPtr ) xmlMalloc ( sizeof ( xmlSchemaVal ) ) ;
if ( val = = NULL ) {
return ( NULL ) ;
}
memset ( val , 0 , sizeof ( xmlSchemaVal ) ) ;
val - > type = type ;
val - > value . str = ( xmlChar * ) value ;
return ( val ) ;
}
2005-02-17 22:00:23 +03:00
/**
* xmlSchemaNewNOTATIONValue :
2005-02-19 21:27:14 +03:00
* @ name : the notation name
* @ ns : the notation namespace name or NULL
2005-02-17 22:00:23 +03:00
*
* Allocate a new NOTATION value .
2005-06-09 14:32:53 +04:00
* The given values are consumed and freed with the struct .
2005-02-17 22:00:23 +03:00
*
* Returns a pointer to the new value or NULL in case of error
*/
xmlSchemaValPtr
xmlSchemaNewNOTATIONValue ( const xmlChar * name ,
const xmlChar * ns )
{
xmlSchemaValPtr val ;
val = xmlSchemaNewValue ( XML_SCHEMAS_NOTATION ) ;
if ( val = = NULL )
return ( NULL ) ;
2005-02-21 16:54:07 +03:00
val - > value . qname . name = ( xmlChar * ) name ;
2005-02-17 22:00:23 +03:00
if ( ns ! = NULL )
2005-02-21 16:54:07 +03:00
val - > value . qname . uri = ( xmlChar * ) ns ;
2005-02-17 22:00:23 +03:00
return ( val ) ;
}
2005-02-17 14:10:44 +03:00
2005-06-09 14:32:53 +04:00
/**
* xmlSchemaNewQNameValue :
* @ namespaceName : the namespace name
* @ localName : the local name
*
* Allocate a new QName value .
* The given values are consumed and freed with the struct .
*
* Returns a pointer to the new value or NULL in case of an error .
*/
xmlSchemaValPtr
xmlSchemaNewQNameValue ( const xmlChar * namespaceName ,
const xmlChar * localName )
{
xmlSchemaValPtr val ;
val = xmlSchemaNewValue ( XML_SCHEMAS_QNAME ) ;
if ( val = = NULL )
return ( NULL ) ;
val - > value . qname . name = ( xmlChar * ) localName ;
val - > value . qname . uri = ( xmlChar * ) namespaceName ;
return ( val ) ;
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaFreeValue :
* @ value : the value to free
*
* Cleanup the default XML Schemas type library
*/
2012-09-11 09:26:36 +04:00
void
2002-04-16 19:50:10 +04:00
xmlSchemaFreeValue ( xmlSchemaValPtr value ) {
2005-06-09 14:32:53 +04:00
xmlSchemaValPtr prev ;
2012-09-11 09:26:36 +04:00
while ( value ! = NULL ) {
2005-06-09 14:32:53 +04:00
switch ( value - > type ) {
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_NORMSTRING :
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NMTOKENS :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_IDREFS :
case XML_SCHEMAS_ENTITY :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_ENTITIES :
2005-06-09 14:32:53 +04:00
case XML_SCHEMAS_ANYURI :
case XML_SCHEMAS_ANYSIMPLETYPE :
if ( value - > value . str ! = NULL )
xmlFree ( value - > value . str ) ;
break ;
case XML_SCHEMAS_NOTATION :
case XML_SCHEMAS_QNAME :
if ( value - > value . qname . uri ! = NULL )
xmlFree ( value - > value . qname . uri ) ;
if ( value - > value . qname . name ! = NULL )
xmlFree ( value - > value . qname . name ) ;
break ;
case XML_SCHEMAS_HEXBINARY :
if ( value - > value . hex . str ! = NULL )
xmlFree ( value - > value . hex . str ) ;
break ;
case XML_SCHEMAS_BASE64BINARY :
if ( value - > value . base64 . str ! = NULL )
xmlFree ( value - > value . base64 . str ) ;
break ;
2023-11-07 23:08:01 +03:00
case XML_SCHEMAS_DECIMAL :
case XML_SCHEMAS_INTEGER :
case XML_SCHEMAS_NNINTEGER :
case XML_SCHEMAS_PINTEGER :
case XML_SCHEMAS_NPINTEGER :
case XML_SCHEMAS_NINTEGER :
case XML_SCHEMAS_INT :
case XML_SCHEMAS_UINT :
case XML_SCHEMAS_LONG :
case XML_SCHEMAS_ULONG :
case XML_SCHEMAS_SHORT :
case XML_SCHEMAS_USHORT :
case XML_SCHEMAS_BYTE :
case XML_SCHEMAS_UBYTE :
if ( value - > value . decimal . str ! = NULL )
xmlFree ( value - > value . decimal . str ) ;
break ;
2005-06-09 14:32:53 +04:00
default :
break ;
}
prev = value ;
value = value - > next ;
xmlFree ( prev ) ;
2012-09-11 09:26:36 +04:00
}
2002-04-16 19:50:10 +04:00
}
/**
* xmlSchemaGetPredefinedType :
* @ name : the type name
* @ ns : the URI of the namespace usually " http://www.w3.org/2001/XMLSchema "
*
* Lookup a type in the default XML Schemas type library
*
* Returns the type if found , NULL otherwise
*/
xmlSchemaTypePtr
xmlSchemaGetPredefinedType ( const xmlChar * name , const xmlChar * ns ) {
2023-03-14 15:55:06 +03:00
if ( ( xmlSchemaTypesInitialized = = 0 ) & &
( xmlSchemaInitTypes ( ) < 0 ) )
return ( NULL ) ;
2002-04-16 19:50:10 +04:00
if ( name = = NULL )
return ( NULL ) ;
return ( ( xmlSchemaTypePtr ) xmlHashLookup2 ( xmlSchemaTypesBank , name , ns ) ) ;
}
2002-05-03 11:29:38 +04:00
2004-06-29 21:04:39 +04:00
/**
* xmlSchemaGetBuiltInListSimpleTypeItemType :
* @ type : the built - in simple type .
*
2004-10-27 21:29:04 +04:00
* Lookup function
*
2004-08-10 18:17:33 +04:00
* Returns the item type of @ type as defined by the built - in datatype
* hierarchy of XML Schema Part 2 : Datatypes , or NULL in case of an error .
2004-06-29 21:04:39 +04:00
*/
xmlSchemaTypePtr
xmlSchemaGetBuiltInListSimpleTypeItemType ( xmlSchemaTypePtr type )
{
2004-11-08 13:52:06 +03:00
if ( ( type = = NULL ) | | ( type - > type ! = XML_SCHEMA_TYPE_BASIC ) )
2004-06-29 21:04:39 +04:00
return ( NULL ) ;
switch ( type - > builtInType ) {
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_NMTOKENS :
2004-06-29 21:04:39 +04:00
return ( xmlSchemaTypeNmtokenDef ) ;
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_IDREFS :
2004-06-29 21:04:39 +04:00
return ( xmlSchemaTypeIdrefDef ) ;
case XML_SCHEMAS_ENTITIES :
return ( xmlSchemaTypeEntityDef ) ;
default :
return ( NULL ) ;
}
}
2002-05-03 11:29:38 +04:00
/****************************************************************
* *
* Convenience macros and functions *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define IS_TZO_CHAR(c) \
( ( c = = 0 ) | | ( c = = ' Z ' ) | | ( c = = ' + ' ) | | ( c = = ' - ' ) )
# define VALID_YEAR(yr) (yr != 0)
# define VALID_MONTH(mon) ((mon >= 1) && (mon <= 12))
/* VALID_DAY should only be used when month is unknown */
# define VALID_DAY(day) ((day >= 1) && (day <= 31))
# define VALID_HOUR(hr) ((hr >= 0) && (hr <= 23))
# define VALID_MIN(min) ((min >= 0) && (min <= 59))
# define VALID_SEC(sec) ((sec >= 0) && (sec < 60))
2019-09-13 13:24:23 +03:00
# define VALID_TZO(tzo) ((tzo >= -840) && (tzo <= 840))
2002-05-03 11:29:38 +04:00
# define IS_LEAP(y) \
( ( ( y % 4 = = 0 ) & & ( y % 100 ! = 0 ) ) | | ( y % 400 = = 0 ) )
2004-03-25 12:35:49 +03:00
static const unsigned int daysInMonth [ 12 ] =
2002-05-03 11:29:38 +04:00
{ 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ;
2004-03-25 12:35:49 +03:00
static const unsigned int daysInMonthLeap [ 12 ] =
2002-05-03 11:29:38 +04:00
{ 31 , 29 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 } ;
2002-05-22 10:40:27 +04:00
# define MAX_DAYINMONTH(yr,mon) \
( IS_LEAP ( yr ) ? daysInMonthLeap [ mon - 1 ] : daysInMonth [ mon - 1 ] )
2002-05-03 11:29:38 +04:00
# define VALID_MDAY(dt) \
( IS_LEAP ( dt - > year ) ? \
( dt - > day < = daysInMonthLeap [ dt - > mon - 1 ] ) : \
( dt - > day < = daysInMonth [ dt - > mon - 1 ] ) )
# define VALID_DATE(dt) \
( VALID_YEAR ( dt - > year ) & & VALID_MONTH ( dt - > mon ) & & VALID_MDAY ( dt ) )
2016-04-11 21:03:19 +03:00
# define VALID_END_OF_DAY(dt) \
( ( dt ) - > hour = = 24 & & ( dt ) - > min = = 0 & & ( dt ) - > sec = = 0 )
2002-05-03 11:29:38 +04:00
# define VALID_TIME(dt) \
2023-11-08 23:59:56 +03:00
( ( ( VALID_HOUR ( ( int ) dt - > hour ) & & VALID_MIN ( ( int ) dt - > min ) & & \
2016-04-11 21:03:19 +03:00
VALID_SEC ( dt - > sec ) ) | | VALID_END_OF_DAY ( dt ) ) & & \
VALID_TZO ( dt - > tzo ) )
2002-05-03 11:29:38 +04:00
# define VALID_DATETIME(dt) \
( VALID_DATE ( dt ) & & VALID_TIME ( dt ) )
2020-06-22 14:08:11 +03:00
# define SECS_PER_MIN 60
# define MINS_PER_HOUR 60
# define HOURS_PER_DAY 24
# define SECS_PER_HOUR (MINS_PER_HOUR * SECS_PER_MIN)
# define SECS_PER_DAY (HOURS_PER_DAY * SECS_PER_HOUR)
# define MINS_PER_DAY (HOURS_PER_DAY * MINS_PER_HOUR)
2002-05-03 11:29:38 +04:00
2002-05-22 10:40:27 +04:00
static const long dayInYearByMonth [ 12 ] =
{ 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 } ;
static const long dayInLeapYearByMonth [ 12 ] =
{ 0 , 31 , 60 , 91 , 121 , 152 , 182 , 213 , 244 , 274 , 305 , 335 } ;
# define DAY_IN_YEAR(day, month, year) \
( ( IS_LEAP ( year ) ? \
dayInLeapYearByMonth [ month - 1 ] : \
dayInYearByMonth [ month - 1 ] ) + day )
2002-05-03 11:29:38 +04:00
/**
* _xmlSchemaParseGYear :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a xs : gYear without time zone and fills in the appropriate
* field of the @ dt structure . @ str is updated to point just after the
* xs : gYear . It is supposed that @ dt - > year is big enough to contain
* the year .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseGYear ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
const xmlChar * cur = * str , * firstChar ;
int isneg = 0 , digcnt = 0 ;
if ( ( ( * cur < ' 0 ' ) | | ( * cur > ' 9 ' ) ) & &
( * cur ! = ' - ' ) & & ( * cur ! = ' + ' ) )
return - 1 ;
if ( * cur = = ' - ' ) {
isneg = 1 ;
cur + + ;
}
firstChar = cur ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
2020-06-21 20:14:23 +03:00
int digit = * cur - ' 0 ' ;
if ( dt - > year > LONG_MAX / 10 )
return 2 ;
dt - > year * = 10 ;
if ( dt - > year > LONG_MAX - digit )
return 2 ;
dt - > year + = digit ;
2002-05-03 11:29:38 +04:00
cur + + ;
digcnt + + ;
}
/* year must be at least 4 digits (CCYY); over 4
* digits cannot have a leading zero . */
if ( ( digcnt < 4 ) | | ( ( digcnt > 4 ) & & ( * firstChar = = ' 0 ' ) ) )
return 1 ;
if ( isneg )
dt - > year = - dt - > year ;
if ( ! VALID_YEAR ( dt - > year ) )
return 2 ;
* str = cur ;
return 0 ;
}
/**
* PARSE_2_DIGITS :
* @ num : the integer to fill in
* @ cur : an # xmlChar *
* @ invalid : an integer
*
* Parses a 2 - digits integer and updates @ num with the value . @ cur is
* updated to point just after the integer .
* In case of error , @ invalid is set to % TRUE , values of @ num and
* @ cur are undefined .
*/
# define PARSE_2_DIGITS(num, cur, invalid) \
if ( ( cur [ 0 ] < ' 0 ' ) | | ( cur [ 0 ] > ' 9 ' ) | | \
( cur [ 1 ] < ' 0 ' ) | | ( cur [ 1 ] > ' 9 ' ) ) \
invalid = 1 ; \
else \
num = ( cur [ 0 ] - ' 0 ' ) * 10 + ( cur [ 1 ] - ' 0 ' ) ; \
cur + = 2 ;
/**
* PARSE_FLOAT :
* @ num : the double to fill in
* @ cur : an # xmlChar *
* @ invalid : an integer
*
* Parses a float and updates @ num with the value . @ cur is
* updated to point just after the float . The float must have a
* 2 - digits integer part and may or may not have a decimal part .
* In case of error , @ invalid is set to % TRUE , values of @ num and
* @ cur are undefined .
*/
# define PARSE_FLOAT(num, cur, invalid) \
PARSE_2_DIGITS ( num , cur , invalid ) ; \
if ( ! invalid & & ( * cur = = ' . ' ) ) { \
double mult = 1 ; \
cur + + ; \
if ( ( * cur < ' 0 ' ) | | ( * cur > ' 9 ' ) ) \
invalid = 1 ; \
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) { \
mult / = 10 ; \
num + = ( * cur - ' 0 ' ) * mult ; \
cur + + ; \
} \
}
/**
* _xmlSchemaParseGMonth :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a xs : gMonth without time zone and fills in the appropriate
* field of the @ dt structure . @ str is updated to point just after the
* xs : gMonth .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseGMonth ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
const xmlChar * cur = * str ;
int ret = 0 ;
2005-04-19 19:58:31 +04:00
unsigned int value = 0 ;
2002-05-03 11:29:38 +04:00
2005-04-19 19:58:31 +04:00
PARSE_2_DIGITS ( value , cur , ret ) ;
2002-05-03 11:29:38 +04:00
if ( ret ! = 0 )
return ret ;
2005-04-19 19:58:31 +04:00
if ( ! VALID_MONTH ( value ) )
2002-05-03 11:29:38 +04:00
return 2 ;
2005-04-19 19:58:31 +04:00
dt - > mon = value ;
2002-05-03 11:29:38 +04:00
* str = cur ;
return 0 ;
}
/**
* _xmlSchemaParseGDay :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a xs : gDay without time zone and fills in the appropriate
* field of the @ dt structure . @ str is updated to point just after the
* xs : gDay .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseGDay ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
const xmlChar * cur = * str ;
int ret = 0 ;
2005-04-19 19:58:31 +04:00
unsigned int value = 0 ;
2002-05-03 11:29:38 +04:00
2005-04-19 19:58:31 +04:00
PARSE_2_DIGITS ( value , cur , ret ) ;
2002-05-03 11:29:38 +04:00
if ( ret ! = 0 )
return ret ;
2005-04-19 19:58:31 +04:00
if ( ! VALID_DAY ( value ) )
2002-05-03 11:29:38 +04:00
return 2 ;
2005-04-19 19:58:31 +04:00
dt - > day = value ;
2002-05-03 11:29:38 +04:00
* str = cur ;
return 0 ;
}
/**
* _xmlSchemaParseTime :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a xs : time without time zone and fills in the appropriate
* fields of the @ dt structure . @ str is updated to point just after the
* xs : time .
* In case of error , values of @ dt fields are undefined .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseTime ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
2012-09-11 09:26:36 +04:00
const xmlChar * cur = * str ;
2002-05-03 11:29:38 +04:00
int ret = 0 ;
2005-05-12 17:10:22 +04:00
int value = 0 ;
2002-05-03 11:29:38 +04:00
2005-04-19 19:58:31 +04:00
PARSE_2_DIGITS ( value , cur , ret ) ;
2002-05-03 11:29:38 +04:00
if ( ret ! = 0 )
2012-09-11 09:26:36 +04:00
return ret ;
2002-05-03 11:29:38 +04:00
if ( * cur ! = ' : ' )
return 1 ;
2016-04-11 21:03:19 +03:00
if ( ! VALID_HOUR ( value ) & & value ! = 24 /* Allow end-of-day hour */ )
2005-04-19 19:58:31 +04:00
return 2 ;
2002-05-03 11:29:38 +04:00
cur + + ;
/* the ':' insures this string is xs:time */
2005-04-19 19:58:31 +04:00
dt - > hour = value ;
2002-05-03 11:29:38 +04:00
2005-04-19 19:58:31 +04:00
PARSE_2_DIGITS ( value , cur , ret ) ;
2002-05-03 11:29:38 +04:00
if ( ret ! = 0 )
return ret ;
2005-04-19 19:58:31 +04:00
if ( ! VALID_MIN ( value ) )
return 2 ;
dt - > min = value ;
2002-05-03 11:29:38 +04:00
if ( * cur ! = ' : ' )
return 1 ;
cur + + ;
PARSE_FLOAT ( dt - > sec , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
2016-04-11 21:03:19 +03:00
if ( ! VALID_TIME ( dt ) )
2002-05-03 11:29:38 +04:00
return 2 ;
* str = cur ;
return 0 ;
}
/**
* _xmlSchemaParseTimeZone :
* @ dt : pointer to a date structure
* @ str : pointer to the string to analyze
*
* Parses a time zone without time zone and fills in the appropriate
* field of the @ dt structure . @ str is updated to point just after the
* time zone .
*
* Returns 0 or the error code
*/
static int
_xmlSchemaParseTimeZone ( xmlSchemaValDatePtr dt , const xmlChar * * str ) {
2006-03-09 21:41:40 +03:00
const xmlChar * cur ;
2002-05-03 11:29:38 +04:00
int ret = 0 ;
if ( str = = NULL )
return - 1 ;
2006-03-09 21:41:40 +03:00
cur = * str ;
2002-05-03 11:29:38 +04:00
switch ( * cur ) {
case 0 :
dt - > tz_flag = 0 ;
dt - > tzo = 0 ;
break ;
case ' Z ' :
dt - > tz_flag = 1 ;
dt - > tzo = 0 ;
cur + + ;
break ;
case ' + ' :
case ' - ' : {
int isneg = 0 , tmp = 0 ;
isneg = ( * cur = = ' - ' ) ;
cur + + ;
PARSE_2_DIGITS ( tmp , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( ! VALID_HOUR ( tmp ) )
return 2 ;
if ( * cur ! = ' : ' )
return 1 ;
cur + + ;
dt - > tzo = tmp * 60 ;
PARSE_2_DIGITS ( tmp , cur , ret ) ;
if ( ret ! = 0 )
return ret ;
if ( ! VALID_MIN ( tmp ) )
return 2 ;
dt - > tzo + = tmp ;
if ( isneg )
dt - > tzo = - dt - > tzo ;
if ( ! VALID_TZO ( dt - > tzo ) )
return 2 ;
2002-05-22 10:40:27 +04:00
dt - > tz_flag = 1 ;
2002-05-03 11:29:38 +04:00
break ;
}
default :
return 1 ;
}
* str = cur ;
return 0 ;
}
2003-08-27 18:15:15 +04:00
/**
* _xmlSchemaBase64Decode :
* @ ch : a character
*
* Converts a base64 encoded character to its base 64 value .
*
* Returns 0 - 63 ( value ) , 64 ( pad ) , or - 1 ( not recognized )
*/
static int
_xmlSchemaBase64Decode ( const xmlChar ch ) {
if ( ( ' A ' < = ch ) & & ( ch < = ' Z ' ) ) return ch - ' A ' ;
if ( ( ' a ' < = ch ) & & ( ch < = ' z ' ) ) return ch - ' a ' + 26 ;
if ( ( ' 0 ' < = ch ) & & ( ch < = ' 9 ' ) ) return ch - ' 0 ' + 52 ;
if ( ' + ' = = ch ) return 62 ;
if ( ' / ' = = ch ) return 63 ;
if ( ' = ' = = ch ) return 64 ;
return - 1 ;
}
2002-05-03 11:29:38 +04:00
/****************************************************************
* *
* XML Schema Dates / Times Datatypes Handling *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* PARSE_DIGITS :
* @ num : the integer to fill in
* @ cur : an # xmlChar *
* @ num_type : an integer flag
*
* Parses a digits integer and updates @ num with the value . @ cur is
* updated to point just after the integer .
* In case of error , @ num_type is set to - 1 , values of @ num and
* @ cur are undefined .
*/
# define PARSE_DIGITS(num, cur, num_type) \
if ( ( * cur < ' 0 ' ) | | ( * cur > ' 9 ' ) ) \
num_type = - 1 ; \
else \
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) { \
num = num * 10 + ( * cur - ' 0 ' ) ; \
cur + + ; \
}
/**
* PARSE_NUM :
* @ num : the double to fill in
* @ cur : an # xmlChar *
* @ num_type : an integer flag
*
* Parses a float or integer and updates @ num with the value . @ cur is
* updated to point just after the number . If the number is a float ,
* then it must have an integer part and a decimal part ; @ num_type will
* be set to 1. If there is no decimal part , @ num_type is set to zero .
* In case of error , @ num_type is set to - 1 , values of @ num and
* @ cur are undefined .
*/
# define PARSE_NUM(num, cur, num_type) \
num = 0 ; \
PARSE_DIGITS ( num , cur , num_type ) ; \
if ( ! num_type & & ( * cur = = ' . ' ) ) { \
double mult = 1 ; \
cur + + ; \
if ( ( * cur < ' 0 ' ) | | ( * cur > ' 9 ' ) ) \
num_type = - 1 ; \
else \
num_type = 1 ; \
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) { \
mult / = 10 ; \
num + = ( * cur - ' 0 ' ) * mult ; \
cur + + ; \
} \
}
/**
2002-05-22 10:40:27 +04:00
* xmlSchemaValidateDates :
2003-03-31 14:13:23 +04:00
* @ type : the expected type or XML_SCHEMAS_UNKNOWN
2002-05-03 11:29:38 +04:00
* @ dateTime : string to analyze
* @ val : the return computed value
*
* Check that @ dateTime conforms to the lexical space of one of the date types .
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
static int
2003-03-31 14:13:23 +04:00
xmlSchemaValidateDates ( xmlSchemaValType type ,
2005-06-09 14:32:53 +04:00
const xmlChar * dateTime , xmlSchemaValPtr * val ,
int collapse ) {
2002-05-03 11:29:38 +04:00
xmlSchemaValPtr dt ;
int ret ;
const xmlChar * cur = dateTime ;
# define RETURN_TYPE_IF_VALID(t) \
if ( IS_TZO_CHAR ( * cur ) ) { \
ret = _xmlSchemaParseTimeZone ( & ( dt - > value . date ) , & cur ) ; \
if ( ret = = 0 ) { \
if ( * cur ! = 0 ) \
goto error ; \
dt - > type = t ; \
2003-03-31 14:13:23 +04:00
goto done ; \
2002-05-03 11:29:38 +04:00
} \
}
if ( dateTime = = NULL )
return - 1 ;
2005-06-09 14:32:53 +04:00
if ( collapse )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2002-05-03 11:29:38 +04:00
if ( ( * cur ! = ' - ' ) & & ( * cur < ' 0 ' ) & & ( * cur > ' 9 ' ) )
return 1 ;
dt = xmlSchemaNewValue ( XML_SCHEMAS_UNKNOWN ) ;
if ( dt = = NULL )
return - 1 ;
if ( ( cur [ 0 ] = = ' - ' ) & & ( cur [ 1 ] = = ' - ' ) ) {
/*
* It ' s an incomplete date ( xs : gMonthDay , xs : gMonth or
* xs : gDay )
*/
cur + = 2 ;
/* is it an xs:gDay? */
if ( * cur = = ' - ' ) {
2003-03-31 14:13:23 +04:00
if ( type = = XML_SCHEMAS_GMONTH )
goto error ;
2002-05-03 11:29:38 +04:00
+ + cur ;
ret = _xmlSchemaParseGDay ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GDAY ) ;
goto error ;
}
/*
* it should be an xs : gMonthDay or xs : gMonth
*/
ret = _xmlSchemaParseGMonth ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
2003-04-09 15:24:17 +04:00
/*
* a ' - ' char could indicate this type is xs : gMonthDay or
* a negative time zone offset . Check for xs : gMonthDay first .
* Also the first three char ' s of a negative tzo ( - MM : SS ) can
* appear to be a valid day ; so even if the day portion
* of the xs : gMonthDay verifies , we must insure it was not
* a tzo .
*/
if ( * cur = = ' - ' ) {
const xmlChar * rewnd = cur ;
cur + + ;
2012-09-11 09:26:36 +04:00
ret = _xmlSchemaParseGDay ( & ( dt - > value . date ) , & cur ) ;
2003-04-09 15:24:17 +04:00
if ( ( ret = = 0 ) & & ( ( * cur = = 0 ) | | ( * cur ! = ' : ' ) ) ) {
/*
* we can use the VALID_MDAY macro to validate the month
* and day because the leap year test will flag year zero
* as a leap year ( even though zero is an invalid year ) .
2005-06-09 14:32:53 +04:00
* FUTURE TODO : Zero will become valid in XML Schema 1.1
* probably .
2003-04-09 15:24:17 +04:00
*/
if ( VALID_MDAY ( ( & ( dt - > value . date ) ) ) ) {
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GMONTHDAY ) ;
2002-05-03 11:29:38 +04:00
2003-04-09 15:24:17 +04:00
goto error ;
}
}
/*
* not xs : gMonthDay so rewind and check if just xs : gMonth
* with an optional time zone .
*/
cur = rewnd ;
}
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GMONTH ) ;
2002-05-03 11:29:38 +04:00
goto error ;
}
/*
* It ' s a right - truncated date or an xs : time .
* Try to parse an xs : time then fallback on right - truncated dates .
*/
if ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
ret = _xmlSchemaParseTime ( & ( dt - > value . date ) , & cur ) ;
if ( ret = = 0 ) {
/* it's an xs:time */
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_TIME ) ;
}
}
/* fallback on date parsing */
cur = dateTime ;
ret = _xmlSchemaParseGYear ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
/* is it an xs:gYear? */
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GYEAR ) ;
if ( * cur ! = ' - ' )
goto error ;
cur + + ;
ret = _xmlSchemaParseGMonth ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
/* is it an xs:gYearMonth? */
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_GYEARMONTH ) ;
if ( * cur ! = ' - ' )
goto error ;
cur + + ;
ret = _xmlSchemaParseGDay ( & ( dt - > value . date ) , & cur ) ;
if ( ( ret ! = 0 ) | | ! VALID_DATE ( ( & ( dt - > value . date ) ) ) )
goto error ;
/* is it an xs:date? */
RETURN_TYPE_IF_VALID ( XML_SCHEMAS_DATE ) ;
if ( * cur ! = ' T ' )
goto error ;
cur + + ;
/* it should be an xs:dateTime */
ret = _xmlSchemaParseTime ( & ( dt - > value . date ) , & cur ) ;
if ( ret ! = 0 )
goto error ;
ret = _xmlSchemaParseTimeZone ( & ( dt - > value . date ) , & cur ) ;
2005-06-09 14:32:53 +04:00
if ( collapse )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-12-10 14:11:12 +03:00
if ( ( ret ! = 0 ) | | ( * cur ! = 0 ) | | ( ! ( VALID_DATETIME ( ( & ( dt - > value . date ) ) ) ) ) )
2002-05-03 11:29:38 +04:00
goto error ;
2003-03-31 14:13:23 +04:00
2002-05-03 11:29:38 +04:00
dt - > type = XML_SCHEMAS_DATETIME ;
2003-03-31 14:13:23 +04:00
done :
2003-04-09 15:24:17 +04:00
# if 1
if ( ( type ! = XML_SCHEMAS_UNKNOWN ) & & ( type ! = dt - > type ) )
goto error ;
# else
/*
* insure the parsed type is equal to or less significant ( right
* truncated ) than the desired type .
*/
if ( ( type ! = XML_SCHEMAS_UNKNOWN ) & & ( type ! = dt - > type ) ) {
/* time only matches time */
if ( ( type = = XML_SCHEMAS_TIME ) & & ( dt - > type = = XML_SCHEMAS_TIME ) )
goto error ;
if ( ( type = = XML_SCHEMAS_DATETIME ) & &
( ( dt - > type ! = XML_SCHEMAS_DATE ) | |
( dt - > type ! = XML_SCHEMAS_GYEARMONTH ) | |
( dt - > type ! = XML_SCHEMAS_GYEAR ) ) )
goto error ;
if ( ( type = = XML_SCHEMAS_DATE ) & &
( ( dt - > type ! = XML_SCHEMAS_GYEAR ) | |
( dt - > type ! = XML_SCHEMAS_GYEARMONTH ) ) )
goto error ;
if ( ( type = = XML_SCHEMAS_GYEARMONTH ) & & ( dt - > type ! = XML_SCHEMAS_GYEAR ) )
goto error ;
if ( ( type = = XML_SCHEMAS_GMONTHDAY ) & & ( dt - > type ! = XML_SCHEMAS_GMONTH ) )
goto error ;
}
2003-03-31 14:13:23 +04:00
# endif
2002-05-03 11:29:38 +04:00
if ( val ! = NULL )
* val = dt ;
2003-03-28 16:29:53 +03:00
else
xmlSchemaFreeValue ( dt ) ;
2002-05-03 11:29:38 +04:00
return 0 ;
error :
if ( dt ! = NULL )
xmlSchemaFreeValue ( dt ) ;
return 1 ;
}
/**
2002-05-22 10:40:27 +04:00
* xmlSchemaValidateDuration :
2002-05-03 11:29:38 +04:00
* @ type : the predefined type
* @ duration : string to analyze
* @ val : the return computed value
*
* Check that @ duration conforms to the lexical space of the duration type .
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
static int
2002-09-26 13:47:36 +04:00
xmlSchemaValidateDuration ( xmlSchemaTypePtr type ATTRIBUTE_UNUSED ,
2005-06-09 14:32:53 +04:00
const xmlChar * duration , xmlSchemaValPtr * val ,
int collapse ) {
2002-05-03 11:29:38 +04:00
const xmlChar * cur = duration ;
xmlSchemaValPtr dur ;
int isneg = 0 ;
unsigned int seq = 0 ;
2020-06-22 14:08:11 +03:00
long days , secs = 0 ;
double sec_frac = 0.0 ;
2002-05-03 11:29:38 +04:00
if ( duration = = NULL )
return - 1 ;
2005-06-09 14:32:53 +04:00
if ( collapse )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2002-05-03 11:29:38 +04:00
if ( * cur = = ' - ' ) {
isneg = 1 ;
cur + + ;
}
/* duration must start with 'P' (after sign) */
if ( * cur + + ! = ' P ' )
return 1 ;
2003-03-28 16:29:53 +03:00
if ( * cur = = 0 )
return 1 ;
2002-05-03 11:29:38 +04:00
dur = xmlSchemaNewValue ( XML_SCHEMAS_DURATION ) ;
if ( dur = = NULL )
return - 1 ;
while ( * cur ! = 0 ) {
2020-06-22 14:08:11 +03:00
long num = 0 ;
size_t has_digits = 0 ;
int has_frac = 0 ;
const xmlChar desig [ ] = { ' Y ' , ' M ' , ' D ' , ' H ' , ' M ' , ' S ' } ;
2002-05-03 11:29:38 +04:00
/* input string should be empty or invalid date/time item */
if ( seq > = sizeof ( desig ) )
goto error ;
/* T designator must be present for time items */
if ( * cur = = ' T ' ) {
2020-06-22 14:08:11 +03:00
if ( seq > 3 )
goto error ;
cur + + ;
seq = 3 ;
2002-05-03 11:29:38 +04:00
} else if ( seq = = 3 )
goto error ;
2020-06-22 14:08:11 +03:00
/* Parse integral part. */
while ( * cur > = ' 0 ' & & * cur < = ' 9 ' ) {
long digit = * cur - ' 0 ' ;
2002-05-03 11:29:38 +04:00
2020-06-22 14:08:11 +03:00
if ( num > LONG_MAX / 10 )
goto error ;
num * = 10 ;
if ( num > LONG_MAX - digit )
goto error ;
num + = digit ;
2002-05-03 11:29:38 +04:00
2020-06-22 14:08:11 +03:00
has_digits = 1 ;
cur + + ;
}
2002-05-03 11:29:38 +04:00
2020-06-22 14:08:11 +03:00
if ( * cur = = ' . ' ) {
/* Parse fractional part. */
double mult = 1.0 ;
cur + + ;
has_frac = 1 ;
while ( * cur > = ' 0 ' & & * cur < = ' 9 ' ) {
mult / = 10.0 ;
sec_frac + = ( * cur - ' 0 ' ) * mult ;
has_digits = 1 ;
cur + + ;
2002-05-03 11:29:38 +04:00
}
2020-06-22 14:08:11 +03:00
}
while ( * cur ! = desig [ seq ] ) {
seq + + ;
/* No T designator or invalid char. */
if ( seq = = 3 | | seq = = sizeof ( desig ) )
2002-05-03 11:29:38 +04:00
goto error ;
}
2005-06-09 14:32:53 +04:00
cur + + ;
2020-06-22 14:08:11 +03:00
if ( ! has_digits | | ( has_frac & & ( seq ! = 5 ) ) )
goto error ;
switch ( seq ) {
case 0 :
/* Year */
if ( num > LONG_MAX / 12 )
goto error ;
dur - > value . dur . mon = num * 12 ;
break ;
case 1 :
/* Month */
if ( dur - > value . dur . mon > LONG_MAX - num )
goto error ;
dur - > value . dur . mon + = num ;
break ;
case 2 :
/* Day */
dur - > value . dur . day = num ;
break ;
case 3 :
/* Hour */
days = num / HOURS_PER_DAY ;
if ( dur - > value . dur . day > LONG_MAX - days )
goto error ;
dur - > value . dur . day + = days ;
secs = ( num % HOURS_PER_DAY ) * SECS_PER_HOUR ;
break ;
case 4 :
/* Minute */
days = num / MINS_PER_DAY ;
if ( dur - > value . dur . day > LONG_MAX - days )
goto error ;
dur - > value . dur . day + = days ;
secs + = ( num % MINS_PER_DAY ) * SECS_PER_MIN ;
break ;
case 5 :
/* Second */
days = num / SECS_PER_DAY ;
if ( dur - > value . dur . day > LONG_MAX - days )
goto error ;
dur - > value . dur . day + = days ;
secs + = num % SECS_PER_DAY ;
break ;
}
seq + + ;
2002-05-03 11:29:38 +04:00
}
2020-06-22 14:08:11 +03:00
days = secs / SECS_PER_DAY ;
if ( dur - > value . dur . day > LONG_MAX - days )
goto error ;
dur - > value . dur . day + = days ;
dur - > value . dur . sec = ( secs % SECS_PER_DAY ) + sec_frac ;
2002-05-03 11:29:38 +04:00
if ( isneg ) {
dur - > value . dur . mon = - dur - > value . dur . mon ;
dur - > value . dur . day = - dur - > value . dur . day ;
dur - > value . dur . sec = - dur - > value . dur . sec ;
}
if ( val ! = NULL )
* val = dur ;
2003-03-28 16:29:53 +03:00
else
xmlSchemaFreeValue ( dur ) ;
2002-05-03 11:29:38 +04:00
return 0 ;
error :
if ( dur ! = NULL )
xmlSchemaFreeValue ( dur ) ;
return 1 ;
}
2003-03-18 19:53:17 +03:00
/**
* xmlSchemaStrip :
* @ value : a value
*
* Removes the leading and ending spaces of a string
*
* Returns the new string or NULL if no change was required .
*/
static xmlChar *
xmlSchemaStrip ( const xmlChar * value ) {
const xmlChar * start = value , * end , * f ;
if ( value = = NULL ) return ( NULL ) ;
2003-10-18 20:20:14 +04:00
while ( ( * start ! = 0 ) & & ( IS_BLANK_CH ( * start ) ) ) start + + ;
2003-03-18 19:53:17 +03:00
end = start ;
while ( * end ! = 0 ) end + + ;
f = end ;
end - - ;
2003-10-18 20:20:14 +04:00
while ( ( end > start ) & & ( IS_BLANK_CH ( * end ) ) ) end - - ;
2003-03-18 19:53:17 +03:00
end + + ;
if ( ( start = = value ) & & ( f = = end ) ) return ( NULL ) ;
return ( xmlStrndup ( start , end - start ) ) ;
}
2003-02-06 11:22:32 +03:00
2004-11-12 17:04:58 +03:00
/**
* xmlSchemaWhiteSpaceReplace :
* @ value : a value
*
* Replaces 0xd , 0x9 and 0xa with a space .
*
* Returns the new string or NULL if no change was required .
*/
xmlChar *
xmlSchemaWhiteSpaceReplace ( const xmlChar * value ) {
2012-09-11 09:26:36 +04:00
const xmlChar * cur = value ;
xmlChar * ret = NULL , * mcur ;
2004-11-12 17:04:58 +03:00
2012-09-11 09:26:36 +04:00
if ( value = = NULL )
2004-11-12 17:04:58 +03:00
return ( NULL ) ;
2012-09-11 09:26:36 +04:00
while ( ( * cur ! = 0 ) & &
2004-11-12 17:04:58 +03:00
( ( ( * cur ) ! = 0xd ) & & ( ( * cur ) ! = 0x9 ) & & ( ( * cur ) ! = 0xa ) ) ) {
cur + + ;
}
if ( * cur = = 0 )
return ( NULL ) ;
ret = xmlStrdup ( value ) ;
/* TODO FIXME: I guess gcc will bark at this. */
mcur = ( xmlChar * ) ( ret + ( cur - value ) ) ;
do {
if ( ( ( * mcur ) = = 0xd ) | | ( ( * mcur ) = = 0x9 ) | | ( ( * mcur ) = = 0xa ) )
* mcur = ' ' ;
mcur + + ;
2012-09-11 09:26:36 +04:00
} while ( * mcur ! = 0 ) ;
2004-11-12 17:04:58 +03:00
return ( ret ) ;
}
2003-03-29 19:41:55 +03:00
/**
* xmlSchemaCollapseString :
* @ value : a value
*
* Removes and normalize white spaces in the string
*
* Returns the new string or NULL if no change was required .
*/
2004-06-29 21:04:39 +04:00
xmlChar *
2003-03-29 19:41:55 +03:00
xmlSchemaCollapseString ( const xmlChar * value ) {
const xmlChar * start = value , * end , * f ;
xmlChar * g ;
int col = 0 ;
if ( value = = NULL ) return ( NULL ) ;
2003-10-18 20:20:14 +04:00
while ( ( * start ! = 0 ) & & ( IS_BLANK_CH ( * start ) ) ) start + + ;
2003-03-29 19:41:55 +03:00
end = start ;
while ( * end ! = 0 ) {
2003-10-18 20:20:14 +04:00
if ( ( * end = = ' ' ) & & ( IS_BLANK_CH ( end [ 1 ] ) ) ) {
2003-03-29 19:41:55 +03:00
col = end - start ;
break ;
} else if ( ( * end = = 0xa ) | | ( * end = = 0x9 ) | | ( * end = = 0xd ) ) {
col = end - start ;
break ;
}
end + + ;
}
if ( col = = 0 ) {
f = end ;
end - - ;
2003-10-18 20:20:14 +04:00
while ( ( end > start ) & & ( IS_BLANK_CH ( * end ) ) ) end - - ;
2003-03-29 19:41:55 +03:00
end + + ;
if ( ( start = = value ) & & ( f = = end ) ) return ( NULL ) ;
return ( xmlStrndup ( start , end - start ) ) ;
}
start = xmlStrdup ( start ) ;
if ( start = = NULL ) return ( NULL ) ;
g = ( xmlChar * ) ( start + col ) ;
end = g ;
while ( * end ! = 0 ) {
2003-10-18 20:20:14 +04:00
if ( IS_BLANK_CH ( * end ) ) {
2003-03-29 19:41:55 +03:00
end + + ;
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * end ) ) end + + ;
2003-03-29 19:41:55 +03:00
if ( * end ! = 0 )
* g + + = ' ' ;
} else
* g + + = * end + + ;
}
* g = 0 ;
return ( ( xmlChar * ) start ) ;
}
2003-03-18 14:39:17 +03:00
/**
* xmlSchemaValAtomicListNode :
* @ type : the predefined atomic type for a token in the list
* @ value : the list value to check
* @ ret : the return computed value
* @ node : the node containing the value
*
* Check that a value conforms to the lexical space of the predefined
* list type . if true a value is computed and returned in @ ret .
*
2003-03-18 19:53:17 +03:00
* Returns the number of items if this validates , a negative error code
* number otherwise
2003-03-18 14:39:17 +03:00
*/
static int
xmlSchemaValAtomicListNode ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * ret , xmlNodePtr node ) {
xmlChar * val , * cur , * endval ;
int nb_values = 0 ;
2003-03-22 00:22:48 +03:00
int tmp = 0 ;
2003-03-18 14:39:17 +03:00
if ( value = = NULL ) {
return ( - 1 ) ;
}
val = xmlStrdup ( value ) ;
if ( val = = NULL ) {
return ( - 1 ) ;
}
2005-01-16 03:05:58 +03:00
if ( ret ! = NULL ) {
* ret = NULL ;
}
2003-03-18 14:39:17 +03:00
cur = val ;
/*
* Split the list
*/
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * cur ) ) * cur + + = 0 ;
2003-03-18 14:39:17 +03:00
while ( * cur ! = 0 ) {
2003-10-18 20:20:14 +04:00
if ( IS_BLANK_CH ( * cur ) ) {
2003-03-18 14:39:17 +03:00
* cur = 0 ;
cur + + ;
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * cur ) ) * cur + + = 0 ;
2003-03-18 14:39:17 +03:00
} else {
nb_values + + ;
cur + + ;
2003-10-18 20:20:14 +04:00
while ( ( * cur ! = 0 ) & & ( ! IS_BLANK_CH ( * cur ) ) ) cur + + ;
2003-03-18 14:39:17 +03:00
}
}
if ( nb_values = = 0 ) {
xmlFree ( val ) ;
2003-03-18 19:53:17 +03:00
return ( nb_values ) ;
2003-03-18 14:39:17 +03:00
}
endval = cur ;
cur = val ;
while ( ( * cur = = 0 ) & & ( cur ! = endval ) ) cur + + ;
while ( cur ! = endval ) {
tmp = xmlSchemaValPredefTypeNode ( type , cur , NULL , node ) ;
if ( tmp ! = 0 )
break ;
while ( * cur ! = 0 ) cur + + ;
while ( ( * cur = = 0 ) & & ( cur ! = endval ) ) cur + + ;
}
2005-01-16 03:05:58 +03:00
/* TODO what return value ? c.f. bug #158628
2003-03-18 14:39:17 +03:00
if ( ret ! = NULL ) {
TODO
2005-01-16 03:05:58 +03:00
} */
xmlFree ( val ) ;
2003-03-18 19:53:17 +03:00
if ( tmp = = 0 )
return ( nb_values ) ;
return ( - 1 ) ;
2003-03-18 14:39:17 +03:00
}
2003-03-31 01:10:09 +04:00
/**
* xmlSchemaParseUInt :
* @ str : pointer to the string R / W
2023-11-07 23:08:01 +03:00
* @ val : pointer to the resulting decimal
2003-03-31 01:10:09 +04:00
*
2023-11-07 23:08:01 +03:00
* Parse an unsigned long into a decimal .
2003-03-31 01:10:09 +04:00
*
2005-03-15 18:50:17 +03:00
* Returns the number of significant digits in the number or
2008-04-03 14:43:52 +04:00
* - 1 if overflow of the capacity and - 2 if it ' s not a number .
2003-03-31 01:10:09 +04:00
*/
2023-11-07 23:08:01 +03:00
static int xmlSchemaParseUInt ( const xmlChar * * str , xmlSchemaValDecimalPtr val ) {
const xmlChar * tmp , * cur = * str ;
int ret = 0 , i = 0 ;
2003-03-31 01:10:09 +04:00
2012-09-11 09:26:36 +04:00
if ( ! ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) )
2008-04-03 14:43:52 +04:00
return ( - 2 ) ;
2005-03-16 19:29:18 +03:00
while ( * cur = = ' 0 ' ) { /* ignore leading zeroes */
cur + + ;
2003-03-31 01:10:09 +04:00
}
2023-11-07 23:08:01 +03:00
/* back up in case there is nothing after the leading zeroes */
if ( ! ( * cur > = ' 0 ' & & * cur < = ' 9 ' ) )
{
- - cur ;
}
2003-03-31 01:10:09 +04:00
tmp = cur ;
while ( ( * tmp ! = 0 ) & & ( * tmp > = ' 0 ' ) & & ( * tmp < = ' 9 ' ) ) {
2005-03-16 19:29:18 +03:00
i + + ; tmp + + ; ret + + ;
2003-03-31 01:10:09 +04:00
}
2023-11-07 23:08:01 +03:00
if ( val - > integralPlaces + val - > fractionalPlaces < ( unsigned ) i + 1 )
{
if ( val - > str ! = NULL )
{
xmlFree ( val - > str ) ;
}
/* sign, dot, fractional 0 and NULL terminator */
val - > str = xmlMalloc ( i + 4 ) ;
2003-03-31 01:10:09 +04:00
}
2023-11-07 23:08:01 +03:00
val - > fractionalPlaces = 1 ;
val - > integralPlaces = i ;
snprintf ( ( char * ) val - > str , i + 4 , " +%.*s.0 " , i , cur ) ;
2003-03-31 01:10:09 +04:00
2023-11-07 23:08:01 +03:00
* str = tmp ;
2003-03-31 01:10:09 +04:00
return ( ret ) ;
}
2021-05-03 18:09:44 +03:00
/*
* xmlSchemaCheckLanguageType
* @ value : the value to check
*
* Check that a value conforms to the lexical space of the language datatype .
* Must conform to [ a - zA - Z ] { 1 , 8 } ( - [ a - zA - Z0 - 9 ] { 1 , 8 } ) *
*
* Returns 1 if this validates , 0 otherwise .
*/
static int
xmlSchemaCheckLanguageType ( const xmlChar * value ) {
int first = 1 , len = 0 ;
const xmlChar * cur = value ;
if ( value = = NULL )
return ( 0 ) ;
while ( cur [ 0 ] ! = 0 ) {
if ( ! ( ( ( cur [ 0 ] > = ' a ' ) & & ( cur [ 0 ] < = ' z ' ) ) | | ( ( cur [ 0 ] > = ' A ' ) & & ( cur [ 0 ] < = ' Z ' ) )
| | ( cur [ 0 ] = = ' - ' )
| | ( ( first = = 0 ) & & ( xmlIsDigit_ch ( cur [ 0 ] ) ) ) ) )
return ( 0 ) ;
if ( cur [ 0 ] = = ' - ' ) {
if ( ( len < 1 ) | | ( len > 8 ) )
return ( 0 ) ;
len = 0 ;
first = 0 ;
}
else
len + + ;
cur + + ;
}
if ( ( len < 1 ) | | ( len > 8 ) )
return ( 0 ) ;
return ( 1 ) ;
}
2002-04-16 19:50:10 +04:00
/**
2003-03-29 19:41:55 +03:00
* xmlSchemaValAtomicType :
2002-04-16 19:50:10 +04:00
* @ type : the predefined type
* @ value : the value to check
* @ val : the return computed value
2003-03-18 03:31:04 +03:00
* @ node : the node containing the value
2019-09-30 18:04:54 +03:00
* flags : flags to control the validation
2002-04-16 19:50:10 +04:00
*
2003-03-29 19:41:55 +03:00
* Check that a value conforms to the lexical space of the atomic type .
2002-04-16 19:50:10 +04:00
* if true a value is computed and returned in @ val .
2004-06-29 21:04:39 +04:00
* This checks the value space for list types as well ( IDREFS , NMTOKENS ) .
2002-04-16 19:50:10 +04:00
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
2003-03-29 19:41:55 +03:00
static int
2003-08-27 18:15:15 +04:00
xmlSchemaValAtomicType ( xmlSchemaTypePtr type , const xmlChar * value ,
2005-06-09 14:32:53 +04:00
xmlSchemaValPtr * val , xmlNodePtr node , int flags ,
xmlSchemaWhitespaceValueType ws ,
int normOnTheFly , int applyNorm , int createStringValue )
2003-08-27 18:15:15 +04:00
{
2002-04-16 19:50:10 +04:00
xmlSchemaValPtr v ;
2003-03-29 19:41:55 +03:00
xmlChar * norm = NULL ;
2003-04-09 15:24:17 +04:00
int ret = 0 ;
2002-04-16 19:50:10 +04:00
2023-03-14 15:55:06 +03:00
if ( ( xmlSchemaTypesInitialized = = 0 ) & &
( xmlSchemaInitTypes ( ) < 0 ) )
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
if ( type = = NULL )
2003-08-27 18:15:15 +04:00
return ( - 1 ) ;
2002-05-22 10:40:27 +04:00
2004-08-26 14:30:44 +04:00
/*
2019-09-30 18:04:54 +03:00
* validating a non existent text node is similar to validating
2004-08-26 14:30:44 +04:00
* an empty one .
*/
if ( value = = NULL )
value = BAD_CAST " " ;
2002-04-16 19:50:10 +04:00
if ( val ! = NULL )
2003-08-27 18:15:15 +04:00
* val = NULL ;
2003-03-29 19:41:55 +03:00
if ( ( flags = = 0 ) & & ( value ! = NULL ) ) {
2004-11-12 17:04:58 +03:00
2004-06-29 21:04:39 +04:00
if ( ( type - > builtInType ! = XML_SCHEMAS_STRING ) & &
2012-09-11 09:26:36 +04:00
( type - > builtInType ! = XML_SCHEMAS_ANYTYPE ) & &
2004-11-12 17:04:58 +03:00
( type - > builtInType ! = XML_SCHEMAS_ANYSIMPLETYPE ) ) {
if ( type - > builtInType = = XML_SCHEMAS_NORMSTRING )
norm = xmlSchemaWhiteSpaceReplace ( value ) ;
else
norm = xmlSchemaCollapseString ( value ) ;
2003-08-27 18:15:15 +04:00
if ( norm ! = NULL )
value = norm ;
}
2003-03-29 19:41:55 +03:00
}
2004-06-29 21:04:39 +04:00
switch ( type - > builtInType ) {
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_UNKNOWN :
2003-08-27 18:15:15 +04:00
goto error ;
modified parsing of <list>, <union>, <restriction>, <sequence>, <choice>,
* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
<sequence>, <choice>, <include>, <import>.
Fixed schema defaults (elementFormDefault, etc.) for included
schemas.
Fixed a bug which reported attributes as invalid on
elements declarations with the built-in type 'anyType'.
Added "lax" validation of the content of elements of type
'anyType'.
Fixed: element declarations with the same name were treated
as duplicate if located in the subtree of <choice> -> <sequence>.
(This was bug 150623, submitted by Roland Lezuo)
Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
by Igor Kapitanker. (This was bug 150647, submitted by Igor
Kapitanker)
* xmlschemastypes.c: Changed the type of anyType to
XML_SCHEMAS_ANYTYPE.
* include/libxml/xmlerror.h: Added schema parser errors.
* result/schemas/bug145246_0_0*
result/schemas/extension1_0_2.err: Changed test results.
* result/schemas/ct-sc-nobase_0_0*
result/schemas/facet-whiteSpace_0_0*
result/schemas/import1_0_0* result/schemas/import2_0_0*
result/schemas/include2_0_0* result/schemas/include3_0_0*
result/schemas/restriction-attr1_0_0*
result/schemas/seq-dubl-elem1_0_0*
result/schemas/xsd-list-itemType_0_0*: Added new rest results.
test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
test/schemas/import2_0* test/schemas/include2_0*
test/schemas/include3_0* test/schemas/restriction-attr1_0*
test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
test/schemas/xsd-list-itemType_0*: Added new tests and missing
files.
2004-08-21 03:09:47 +04:00
case XML_SCHEMAS_ANYTYPE :
case XML_SCHEMAS_ANYSIMPLETYPE :
2005-06-09 14:32:53 +04:00
if ( ( createStringValue ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_ANYSIMPLETYPE ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
2012-09-11 09:26:36 +04:00
}
2005-06-09 14:32:53 +04:00
}
modified parsing of <list>, <union>, <restriction>, <sequence>, <choice>,
* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
<sequence>, <choice>, <include>, <import>.
Fixed schema defaults (elementFormDefault, etc.) for included
schemas.
Fixed a bug which reported attributes as invalid on
elements declarations with the built-in type 'anyType'.
Added "lax" validation of the content of elements of type
'anyType'.
Fixed: element declarations with the same name were treated
as duplicate if located in the subtree of <choice> -> <sequence>.
(This was bug 150623, submitted by Roland Lezuo)
Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
by Igor Kapitanker. (This was bug 150647, submitted by Igor
Kapitanker)
* xmlschemastypes.c: Changed the type of anyType to
XML_SCHEMAS_ANYTYPE.
* include/libxml/xmlerror.h: Added schema parser errors.
* result/schemas/bug145246_0_0*
result/schemas/extension1_0_2.err: Changed test results.
* result/schemas/ct-sc-nobase_0_0*
result/schemas/facet-whiteSpace_0_0*
result/schemas/import1_0_0* result/schemas/import2_0_0*
result/schemas/include2_0_0* result/schemas/include3_0_0*
result/schemas/restriction-attr1_0_0*
result/schemas/seq-dubl-elem1_0_0*
result/schemas/xsd-list-itemType_0_0*: Added new rest results.
test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
test/schemas/import2_0* test/schemas/include2_0*
test/schemas/include3_0* test/schemas/restriction-attr1_0*
test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
test/schemas/xsd-list-itemType_0*: Added new tests and missing
files.
2004-08-21 03:09:47 +04:00
goto return0 ;
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_STRING :
2005-06-09 14:32:53 +04:00
if ( ! normOnTheFly ) {
const xmlChar * cur = value ;
if ( ws = = XML_SCHEMA_WHITESPACE_REPLACE ) {
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else {
cur + + ;
}
}
} else if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE ) {
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else if IS_WSP_SPACE_CH ( * cur ) {
cur + + ;
if IS_WSP_SPACE_CH ( * cur )
goto return1 ;
} else {
cur + + ;
}
}
}
}
if ( createStringValue & & ( val ! = NULL ) ) {
if ( applyNorm ) {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
norm = xmlSchemaCollapseString ( value ) ;
else if ( ws = = XML_SCHEMA_WHITESPACE_REPLACE )
norm = xmlSchemaWhiteSpaceReplace ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
v = xmlSchemaNewValue ( XML_SCHEMAS_STRING ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
2003-08-27 18:15:15 +04:00
goto return0 ;
2004-01-22 10:27:45 +03:00
case XML_SCHEMAS_NORMSTRING : {
2005-06-09 14:32:53 +04:00
if ( normOnTheFly ) {
if ( applyNorm ) {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
norm = xmlSchemaCollapseString ( value ) ;
else
norm = xmlSchemaWhiteSpaceReplace ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
} else {
const xmlChar * cur = value ;
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else {
cur + + ;
}
}
}
2004-01-22 10:27:45 +03:00
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NORMSTRING ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
2003-08-27 18:15:15 +04:00
case XML_SCHEMAS_DECIMAL : {
2005-03-11 18:55:14 +03:00
const xmlChar * cur = value ;
2023-11-07 23:08:01 +03:00
const xmlChar * numStart , * numEnd ;
xmlSchemaValDecimal decimal ;
xmlChar sign ;
memset ( & decimal , 0 , sizeof ( decimal ) ) ;
2003-08-27 18:15:15 +04:00
2005-11-28 19:36:30 +03:00
if ( ( cur = = NULL ) | | ( * cur = = 0 ) )
2003-08-27 18:15:15 +04:00
goto return1 ;
2005-06-09 14:32:53 +04:00
2005-11-28 19:36:30 +03:00
/*
* xs : decimal has a whitespace - facet value of ' collapse ' .
*/
2005-06-09 14:32:53 +04:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-11-28 19:36:30 +03:00
/*
* First we handle an optional sign .
*/
2023-11-07 23:08:01 +03:00
sign = ' + ' ;
2005-11-28 19:36:30 +03:00
if ( * cur = = ' - ' ) {
2023-11-07 23:08:01 +03:00
sign = ' - ' ;
2003-08-27 18:15:15 +04:00
cur + + ;
2005-11-28 19:36:30 +03:00
} else if ( * cur = = ' + ' )
2003-08-27 18:15:15 +04:00
cur + + ;
2005-11-28 19:36:30 +03:00
/*
* Disallow : " " , " - " , " - "
*/
if ( * cur = = 0 )
goto return1 ;
2023-11-07 23:08:01 +03:00
2005-04-18 14:57:04 +04:00
/*
* Skip leading zeroes .
*/
2005-11-28 19:36:30 +03:00
while ( * cur = = ' 0 ' ) {
2005-03-11 18:55:14 +03:00
cur + + ;
}
2023-11-07 23:08:01 +03:00
numStart = cur ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
+ + cur ;
+ + decimal . integralPlaces ;
}
if ( * cur = = ' . ' ) {
+ + cur ;
}
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
+ + cur ;
+ + decimal . fractionalPlaces ;
}
/* disallow "." */
if (
decimal . fractionalPlaces = = 0 & & decimal . integralPlaces = = 0
& & ( numStart = = value | | numStart [ - 1 ] ! = ' 0 ' )
) {
goto return1 ;
}
numEnd = cur ;
/* find if there are trailing FRACTIONAL zeroes, and deal with them if necessary */
while ( numEnd > numStart & & decimal . fractionalPlaces & & numEnd [ - 1 ] = = ' 0 ' ) {
- - numEnd ;
- - decimal . fractionalPlaces ;
}
2005-06-09 14:32:53 +04:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-03-11 18:55:14 +03:00
if ( * cur ! = 0 )
2005-11-28 19:36:30 +03:00
goto return1 ; /* error if any extraneous chars */
2003-08-27 18:15:15 +04:00
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_DECIMAL ) ;
if ( v ! = NULL ) {
2023-11-07 23:08:01 +03:00
/* create a standardized representation */
size_t bufsize ;
const char * integralStart = ( const char * ) numStart ;
const char * fractionalStart = ( const char * ) numEnd - decimal . fractionalPlaces ;
if ( decimal . integralPlaces = = 0 )
{
integralStart = " 0 " ;
decimal . integralPlaces = 1 ;
}
if ( decimal . fractionalPlaces = = 0 )
{
fractionalStart = " 0 " ;
decimal . fractionalPlaces = 1 ;
}
/* 3 = sign, dot, NULL terminator */
bufsize = decimal . integralPlaces + decimal . fractionalPlaces + 3 ;
decimal . str = xmlMalloc ( bufsize ) ;
if ( ! decimal . str )
{
goto error ;
}
snprintf ( ( char * ) decimal . str , bufsize , " %c%.*s.%.*s " , sign , decimal . integralPlaces , integralStart ,
decimal . fractionalPlaces , fractionalStart ) ;
v - > value . decimal = decimal ;
2003-08-27 18:15:15 +04:00
* val = v ;
}
2023-11-07 23:08:01 +03:00
else
{
goto error ;
}
2003-08-27 18:15:15 +04:00
}
goto return0 ;
}
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_TIME :
case XML_SCHEMAS_GDAY :
case XML_SCHEMAS_GMONTH :
case XML_SCHEMAS_GMONTHDAY :
case XML_SCHEMAS_GYEAR :
case XML_SCHEMAS_GYEARMONTH :
case XML_SCHEMAS_DATE :
case XML_SCHEMAS_DATETIME :
2005-06-09 14:32:53 +04:00
ret = xmlSchemaValidateDates ( type - > builtInType , value , val ,
normOnTheFly ) ;
2003-08-27 18:15:15 +04:00
break ;
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_DURATION :
2005-06-09 14:32:53 +04:00
ret = xmlSchemaValidateDuration ( type , value , val ,
normOnTheFly ) ;
2003-08-27 18:15:15 +04:00
break ;
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_FLOAT :
2010-07-28 13:41:23 +04:00
case XML_SCHEMAS_DOUBLE : {
2003-08-27 18:15:15 +04:00
const xmlChar * cur = value ;
int neg = 0 ;
2010-07-28 13:41:23 +04:00
int digits_before = 0 ;
int digits_after = 0 ;
2003-08-27 18:15:15 +04:00
2005-06-09 14:32:53 +04:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2003-08-27 18:15:15 +04:00
if ( ( cur [ 0 ] = = ' N ' ) & & ( cur [ 1 ] = = ' a ' ) & & ( cur [ 2 ] = = ' N ' ) ) {
cur + = 3 ;
if ( * cur ! = 0 )
goto return1 ;
if ( val ! = NULL ) {
if ( type = = xmlSchemaTypeFloatDef ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_FLOAT ) ;
if ( v ! = NULL ) {
2024-06-16 00:53:04 +03:00
v - > value . f = ( float ) xmlSchemaNAN ;
2003-08-27 18:15:15 +04:00
} else {
xmlSchemaFreeValue ( v ) ;
goto error ;
}
} else {
v = xmlSchemaNewValue ( XML_SCHEMAS_DOUBLE ) ;
if ( v ! = NULL ) {
2024-06-16 00:53:04 +03:00
v - > value . d = xmlSchemaNAN ;
2003-08-27 18:15:15 +04:00
} else {
xmlSchemaFreeValue ( v ) ;
goto error ;
}
}
* val = v ;
}
goto return0 ;
}
if ( * cur = = ' - ' ) {
neg = 1 ;
cur + + ;
}
if ( ( cur [ 0 ] = = ' I ' ) & & ( cur [ 1 ] = = ' N ' ) & & ( cur [ 2 ] = = ' F ' ) ) {
cur + = 3 ;
if ( * cur ! = 0 )
goto return1 ;
if ( val ! = NULL ) {
if ( type = = xmlSchemaTypeFloatDef ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_FLOAT ) ;
if ( v ! = NULL ) {
if ( neg )
2024-06-16 00:53:04 +03:00
v - > value . f = ( float ) xmlSchemaNINF ;
2003-08-27 18:15:15 +04:00
else
2024-06-16 00:53:04 +03:00
v - > value . f = ( float ) xmlSchemaPINF ;
2003-08-27 18:15:15 +04:00
} else {
xmlSchemaFreeValue ( v ) ;
goto error ;
}
} else {
v = xmlSchemaNewValue ( XML_SCHEMAS_DOUBLE ) ;
if ( v ! = NULL ) {
if ( neg )
2024-06-16 00:53:04 +03:00
v - > value . d = xmlSchemaNINF ;
2003-08-27 18:15:15 +04:00
else
2024-06-16 00:53:04 +03:00
v - > value . d = xmlSchemaPINF ;
2003-08-27 18:15:15 +04:00
} else {
xmlSchemaFreeValue ( v ) ;
goto error ;
}
}
* val = v ;
}
goto return0 ;
}
if ( ( neg = = 0 ) & & ( * cur = = ' + ' ) )
cur + + ;
if ( ( cur [ 0 ] = = 0 ) | | ( cur [ 0 ] = = ' + ' ) | | ( cur [ 0 ] = = ' - ' ) )
goto return1 ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
cur + + ;
2010-07-28 13:41:23 +04:00
digits_before + + ;
2003-08-27 18:15:15 +04:00
}
if ( * cur = = ' . ' ) {
cur + + ;
2010-07-28 13:41:23 +04:00
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
2003-08-27 18:15:15 +04:00
cur + + ;
2010-07-28 13:41:23 +04:00
digits_after + + ;
}
2003-08-27 18:15:15 +04:00
}
2010-07-28 16:49:55 +04:00
if ( ( digits_before = = 0 ) & & ( digits_after = = 0 ) )
2010-07-28 13:41:23 +04:00
goto return1 ;
2003-08-27 18:15:15 +04:00
if ( ( * cur = = ' e ' ) | | ( * cur = = ' E ' ) ) {
cur + + ;
if ( ( * cur = = ' - ' ) | | ( * cur = = ' + ' ) )
cur + + ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) )
cur + + ;
}
2005-06-09 14:32:53 +04:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2003-08-27 18:15:15 +04:00
if ( * cur ! = 0 )
goto return1 ;
if ( val ! = NULL ) {
if ( type = = xmlSchemaTypeFloatDef ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_FLOAT ) ;
if ( v ! = NULL ) {
2005-03-15 17:58:11 +03:00
/*
* TODO : sscanf seems not to give the correct
* value for extremely high / low values .
* E . g . " 1E-149 " results in zero .
*/
2003-10-10 04:49:42 +04:00
if ( sscanf ( ( const char * ) value , " %f " ,
2003-08-27 18:15:15 +04:00
& ( v - > value . f ) ) = = 1 ) {
2005-03-15 17:58:11 +03:00
* val = v ;
2003-08-27 18:15:15 +04:00
} else {
xmlSchemaFreeValue ( v ) ;
goto return1 ;
}
} else {
goto error ;
}
} else {
v = xmlSchemaNewValue ( XML_SCHEMAS_DOUBLE ) ;
if ( v ! = NULL ) {
2005-03-15 17:58:11 +03:00
/*
* TODO : sscanf seems not to give the correct
* value for extremely high / low values .
*/
2003-10-10 04:49:42 +04:00
if ( sscanf ( ( const char * ) value , " %lf " ,
2003-08-27 18:15:15 +04:00
& ( v - > value . d ) ) = = 1 ) {
* val = v ;
} else {
xmlSchemaFreeValue ( v ) ;
goto return1 ;
}
} else {
goto error ;
}
}
}
goto return0 ;
}
case XML_SCHEMAS_BOOLEAN : {
const xmlChar * cur = value ;
2005-06-09 14:32:53 +04:00
if ( normOnTheFly ) {
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
if ( * cur = = ' 0 ' ) {
ret = 0 ;
cur + + ;
} else if ( * cur = = ' 1 ' ) {
ret = 1 ;
cur + + ;
} else if ( * cur = = ' t ' ) {
cur + + ;
if ( ( * cur + + = = ' r ' ) & & ( * cur + + = = ' u ' ) & &
( * cur + + = = ' e ' ) ) {
ret = 1 ;
} else
goto return1 ;
} else if ( * cur = = ' f ' ) {
cur + + ;
if ( ( * cur + + = = ' a ' ) & & ( * cur + + = = ' l ' ) & &
( * cur + + = = ' s ' ) & & ( * cur + + = = ' e ' ) ) {
ret = 0 ;
} else
goto return1 ;
2006-02-20 16:37:55 +03:00
} else
goto return1 ;
2005-06-09 14:32:53 +04:00
if ( * cur ! = 0 ) {
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
if ( * cur ! = 0 )
goto return1 ;
}
} else {
if ( ( cur [ 0 ] = = ' 0 ' ) & & ( cur [ 1 ] = = 0 ) )
ret = 0 ;
else if ( ( cur [ 0 ] = = ' 1 ' ) & & ( cur [ 1 ] = = 0 ) )
ret = 1 ;
else if ( ( cur [ 0 ] = = ' t ' ) & & ( cur [ 1 ] = = ' r ' )
& & ( cur [ 2 ] = = ' u ' ) & & ( cur [ 3 ] = = ' e ' )
& & ( cur [ 4 ] = = 0 ) )
ret = 1 ;
else if ( ( cur [ 0 ] = = ' f ' ) & & ( cur [ 1 ] = = ' a ' )
& & ( cur [ 2 ] = = ' l ' ) & & ( cur [ 3 ] = = ' s ' )
& & ( cur [ 4 ] = = ' e ' ) & & ( cur [ 5 ] = = 0 ) )
ret = 0 ;
else
goto return1 ;
}
2003-08-27 18:15:15 +04:00
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_BOOLEAN ) ;
if ( v ! = NULL ) {
v - > value . b = ret ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
case XML_SCHEMAS_TOKEN : {
const xmlChar * cur = value ;
2005-06-09 14:32:53 +04:00
if ( ! normOnTheFly ) {
while ( * cur ! = 0 ) {
if ( ( * cur = = 0xd ) | | ( * cur = = 0xa ) | | ( * cur = = 0x9 ) ) {
goto return1 ;
} else if ( * cur = = ' ' ) {
cur + + ;
if ( * cur = = 0 )
goto return1 ;
if ( * cur = = ' ' )
goto return1 ;
} else {
cur + + ;
}
2012-09-11 09:26:36 +04:00
}
}
2003-08-27 18:15:15 +04:00
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_TOKEN ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_LANGUAGE :
2020-06-21 16:21:45 +03:00
if ( ( norm = = NULL ) & & ( normOnTheFly ) ) {
2005-06-09 14:32:53 +04:00
norm = xmlSchemaCollapseString ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
2021-05-03 18:09:44 +03:00
if ( xmlSchemaCheckLanguageType ( value ) = = 1 ) {
2003-08-27 18:15:15 +04:00
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_LANGUAGE ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
goto return1 ;
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_NMTOKEN :
2003-08-27 18:15:15 +04:00
if ( xmlValidateNMToken ( value , 1 ) = = 0 ) {
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NMTOKEN ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto return0 ;
}
goto return1 ;
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_NMTOKENS :
2003-08-27 18:15:15 +04:00
ret = xmlSchemaValAtomicListNode ( xmlSchemaTypeNmtokenDef ,
value , val , node ) ;
if ( ret > 0 )
ret = 0 ;
else
ret = 1 ;
goto done ;
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_NAME :
2003-08-27 18:15:15 +04:00
ret = xmlValidateName ( value , 1 ) ;
2005-01-16 22:00:15 +03:00
if ( ( ret = = 0 ) & & ( val ! = NULL ) & & ( value ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NAME ) ;
if ( v ! = NULL ) {
const xmlChar * start = value , * end ;
while ( IS_BLANK_CH ( * start ) ) start + + ;
end = start ;
while ( ( * end ! = 0 ) & & ( ! IS_BLANK_CH ( * end ) ) ) end + + ;
v - > value . str = xmlStrndup ( start , end - start ) ;
* val = v ;
} else {
goto error ;
}
2003-08-27 18:15:15 +04:00
}
goto done ;
case XML_SCHEMAS_QNAME : {
2005-06-09 18:54:59 +04:00
const xmlChar * uri = NULL ;
2003-08-27 18:15:15 +04:00
xmlChar * local = NULL ;
ret = xmlValidateQName ( value , 1 ) ;
2005-06-09 18:54:59 +04:00
if ( ret ! = 0 )
goto done ;
if ( node ! = NULL ) {
2003-08-27 18:15:15 +04:00
xmlChar * prefix ;
2005-06-09 18:54:59 +04:00
xmlNsPtr ns ;
2003-08-27 18:15:15 +04:00
local = xmlSplitQName2 ( value , & prefix ) ;
2005-06-09 18:54:59 +04:00
ns = xmlSearchNs ( node - > doc , node , prefix ) ;
if ( ( ns = = NULL ) & & ( prefix ! = NULL ) ) {
xmlFree ( prefix ) ;
if ( local ! = NULL )
xmlFree ( local ) ;
goto return1 ;
}
if ( ns ! = NULL )
uri = ns - > href ;
2003-08-27 18:15:15 +04:00
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
}
2005-06-09 18:54:59 +04:00
if ( val ! = NULL ) {
2003-08-27 18:15:15 +04:00
v = xmlSchemaNewValue ( XML_SCHEMAS_QNAME ) ;
2005-06-09 18:54:59 +04:00
if ( v = = NULL ) {
if ( local ! = NULL )
xmlFree ( local ) ;
goto error ;
}
if ( local ! = NULL )
v - > value . qname . name = local ;
else
v - > value . qname . name = xmlStrdup ( value ) ;
if ( uri ! = NULL )
v - > value . qname . uri = xmlStrdup ( uri ) ;
* val = v ;
} else
if ( local ! = NULL )
xmlFree ( local ) ;
2003-08-27 18:15:15 +04:00
goto done ;
}
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_NCNAME :
2003-08-27 18:15:15 +04:00
ret = xmlValidateNCName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NCNAME ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
goto done ;
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_ID :
2003-08-27 18:15:15 +04:00
ret = xmlValidateNCName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_ID ) ;
if ( v ! = NULL ) {
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
} else {
goto error ;
}
}
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
/*
* NOTE : the IDness might have already be declared in the DTD
*/
if ( attr - > atype ! = XML_ATTRIBUTE_ID ) {
xmlChar * strip ;
2024-02-29 21:38:29 +03:00
int res ;
2003-08-27 18:15:15 +04:00
strip = xmlSchemaStrip ( value ) ;
if ( strip ! = NULL ) {
2024-02-29 21:38:29 +03:00
res = xmlAddIDSafe ( attr , strip ) ;
2003-08-27 18:15:15 +04:00
xmlFree ( strip ) ;
} else
2024-02-29 21:38:29 +03:00
res = xmlAddIDSafe ( attr , value ) ;
if ( res < 0 ) {
goto error ;
} else if ( res = = 0 ) {
2003-08-27 18:15:15 +04:00
ret = 2 ;
}
}
}
goto done ;
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_IDREF :
2003-08-27 18:15:15 +04:00
ret = xmlValidateNCName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
2005-02-17 14:10:44 +03:00
v = xmlSchemaNewValue ( XML_SCHEMAS_IDREF ) ;
if ( v = = NULL )
goto error ;
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
2003-08-27 18:15:15 +04:00
}
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
xmlChar * strip ;
strip = xmlSchemaStrip ( value ) ;
if ( strip ! = NULL ) {
xmlAddRef ( NULL , node - > doc , strip , attr ) ;
xmlFree ( strip ) ;
} else
xmlAddRef ( NULL , node - > doc , value , attr ) ;
attr - > atype = XML_ATTRIBUTE_IDREF ;
}
goto done ;
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_IDREFS :
2003-08-27 18:15:15 +04:00
ret = xmlSchemaValAtomicListNode ( xmlSchemaTypeIdrefDef ,
value , val , node ) ;
if ( ret < 0 )
ret = 2 ;
else
ret = 0 ;
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
2003-03-20 00:02:29 +03:00
2003-08-27 18:15:15 +04:00
attr - > atype = XML_ATTRIBUTE_IDREFS ;
}
goto done ;
case XML_SCHEMAS_ENTITY : {
xmlChar * strip ;
ret = xmlValidateNCName ( value , 1 ) ;
if ( ( node = = NULL ) | | ( node - > doc = = NULL ) )
ret = 3 ;
if ( ret = = 0 ) {
xmlEntityPtr ent ;
strip = xmlSchemaStrip ( value ) ;
if ( strip ! = NULL ) {
ent = xmlGetDocEntity ( node - > doc , strip ) ;
xmlFree ( strip ) ;
} else {
ent = xmlGetDocEntity ( node - > doc , value ) ;
}
if ( ( ent = = NULL ) | |
( ent - > etype ! =
XML_EXTERNAL_GENERAL_UNPARSED_ENTITY ) )
ret = 4 ;
}
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
2023-12-18 21:51:32 +03:00
/* TODO */
2003-08-27 18:15:15 +04:00
}
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
2003-03-18 19:53:17 +03:00
2003-08-27 18:15:15 +04:00
attr - > atype = XML_ATTRIBUTE_ENTITY ;
}
goto done ;
}
2003-03-29 19:41:55 +03:00
case XML_SCHEMAS_ENTITIES :
2003-08-27 18:15:15 +04:00
if ( ( node = = NULL ) | | ( node - > doc = = NULL ) )
goto return3 ;
ret = xmlSchemaValAtomicListNode ( xmlSchemaTypeEntityDef ,
value , val , node ) ;
if ( ret < = 0 )
ret = 1 ;
else
ret = 0 ;
if ( ( ret = = 0 ) & & ( node ! = NULL ) & &
( node - > type = = XML_ATTRIBUTE_NODE ) ) {
xmlAttrPtr attr = ( xmlAttrPtr ) node ;
attr - > atype = XML_ATTRIBUTE_ENTITIES ;
}
goto done ;
case XML_SCHEMAS_NOTATION : {
xmlChar * uri = NULL ;
xmlChar * local = NULL ;
ret = xmlValidateQName ( value , 1 ) ;
if ( ( ret = = 0 ) & & ( node ! = NULL ) ) {
xmlChar * prefix ;
local = xmlSplitQName2 ( value , & prefix ) ;
if ( prefix ! = NULL ) {
xmlNsPtr ns ;
ns = xmlSearchNs ( node - > doc , node , prefix ) ;
if ( ns = = NULL )
ret = 1 ;
else if ( val ! = NULL )
uri = xmlStrdup ( ns - > href ) ;
}
if ( ( local ! = NULL ) & & ( ( val = = NULL ) | | ( ret ! = 0 ) ) )
xmlFree ( local ) ;
if ( prefix ! = NULL )
xmlFree ( prefix ) ;
}
if ( ( node = = NULL ) | | ( node - > doc = = NULL ) )
ret = 3 ;
if ( ret = = 0 ) {
2024-06-16 01:39:39 +03:00
xmlNotationPtr nota ;
nota = xmlGetDtdNotationDesc ( node - > doc - > intSubset , value ) ;
if ( ( nota = = NULL ) & & ( node - > doc - > extSubset ! = NULL ) )
nota = xmlGetDtdNotationDesc ( node - > doc - > extSubset ,
value ) ;
if ( nota ! = NULL )
2003-08-27 18:15:15 +04:00
ret = 0 ;
else
ret = 1 ;
}
if ( ( ret = = 0 ) & & ( val ! = NULL ) ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_NOTATION ) ;
if ( v ! = NULL ) {
if ( local ! = NULL )
v - > value . qname . name = local ;
else
v - > value . qname . name = xmlStrdup ( value ) ;
if ( uri ! = NULL )
v - > value . qname . uri = uri ;
* val = v ;
} else {
if ( local ! = NULL )
xmlFree ( local ) ;
if ( uri ! = NULL )
xmlFree ( uri ) ;
goto error ;
}
}
goto done ;
2003-07-07 01:13:49 +04:00
}
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_ANYURI : {
2004-03-14 15:20:15 +03:00
if ( * value ! = 0 ) {
2005-06-09 14:32:53 +04:00
xmlURIPtr uri ;
2009-08-07 18:42:24 +04:00
xmlChar * tmpval , * cur ;
2019-10-14 17:35:00 +03:00
if ( ( norm = = NULL ) & & ( normOnTheFly ) ) {
2005-06-09 14:32:53 +04:00
norm = xmlSchemaCollapseString ( value ) ;
if ( norm ! = NULL )
value = norm ;
}
2009-08-07 18:42:24 +04:00
tmpval = xmlStrdup ( value ) ;
2023-03-05 16:08:15 +03:00
if ( tmpval = = NULL )
goto error ;
2009-08-07 18:42:24 +04:00
for ( cur = tmpval ; * cur ; + + cur ) {
if ( * cur < 32 | | * cur > = 127 | | * cur = = ' ' | |
* cur = = ' < ' | | * cur = = ' > ' | | * cur = = ' " ' | |
* cur = = ' { ' | | * cur = = ' } ' | | * cur = = ' | ' | |
* cur = = ' \\ ' | | * cur = = ' ^ ' | | * cur = = ' ` ' | |
* cur = = ' \' ' )
* cur = ' _ ' ;
}
uri = xmlParseURI ( ( const char * ) tmpval ) ;
xmlFree ( tmpval ) ;
2004-03-14 15:20:15 +03:00
if ( uri = = NULL )
goto return1 ;
xmlFreeURI ( uri ) ;
}
2003-07-07 01:13:49 +04:00
2003-08-27 18:15:15 +04:00
if ( val ! = NULL ) {
2004-03-14 15:20:15 +03:00
v = xmlSchemaNewValue ( XML_SCHEMAS_ANYURI ) ;
if ( v = = NULL )
goto error ;
v - > value . str = xmlStrdup ( value ) ;
* val = v ;
2003-08-27 18:15:15 +04:00
}
goto return0 ;
}
case XML_SCHEMAS_HEXBINARY : {
2005-06-09 17:14:38 +04:00
const xmlChar * cur = value , * start ;
2003-08-27 18:15:15 +04:00
xmlChar * base ;
int total , i = 0 ;
2003-07-07 01:13:49 +04:00
2004-08-31 12:42:17 +04:00
if ( cur = = NULL )
2003-08-27 18:15:15 +04:00
goto return1 ;
2003-07-07 01:13:49 +04:00
2005-06-09 14:32:53 +04:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-06-09 17:14:38 +04:00
start = cur ;
2003-08-27 18:15:15 +04:00
while ( ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) | |
( ( * cur > = ' A ' ) & & ( * cur < = ' F ' ) ) | |
( ( * cur > = ' a ' ) & & ( * cur < = ' f ' ) ) ) {
i + + ;
cur + + ;
}
2005-06-09 14:32:53 +04:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2003-07-07 01:13:49 +04:00
2003-08-27 18:15:15 +04:00
if ( * cur ! = 0 )
goto return1 ;
if ( ( i % 2 ) ! = 0 )
2003-08-08 18:00:28 +04:00
goto return1 ;
2003-07-07 01:13:49 +04:00
2003-08-27 18:15:15 +04:00
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_HEXBINARY ) ;
if ( v = = NULL )
goto error ;
2005-06-09 14:32:53 +04:00
/*
* Copy only the normalized piece .
* CRITICAL TODO : Check this .
*/
2005-06-09 17:14:38 +04:00
cur = xmlStrndup ( start , i ) ;
2003-08-27 18:15:15 +04:00
if ( cur = = NULL ) {
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( ) ;
2003-08-27 18:15:15 +04:00
xmlFree ( v ) ;
goto return1 ;
}
total = i / 2 ; /* number of octets */
2003-08-08 18:00:28 +04:00
2003-08-27 18:15:15 +04:00
base = ( xmlChar * ) cur ;
while ( i - - > 0 ) {
if ( * base > = ' a ' )
* base = * base - ( ' a ' - ' A ' ) ;
base + + ;
}
2003-08-08 18:00:28 +04:00
2003-08-27 18:15:15 +04:00
v - > value . hex . str = ( xmlChar * ) cur ;
v - > value . hex . total = total ;
* val = v ;
}
goto return0 ;
}
case XML_SCHEMAS_BASE64BINARY : {
/* ISSUE:
2012-09-11 09:26:36 +04:00
*
2003-08-27 18:15:15 +04:00
* Ignore all stray characters ? ( yes , currently )
* Worry about long lines ? ( no , currently )
2012-09-11 09:26:36 +04:00
*
2003-08-27 18:15:15 +04:00
* rfc2045 . txt :
2012-09-11 09:26:36 +04:00
*
2003-08-27 18:15:15 +04:00
* " The encoded output stream must be represented in lines of
* no more than 76 characters each . All line breaks or other
* characters not found in Table 1 must be ignored by decoding
* software . In base64 data , characters other than those in
* Table 1 , line breaks , and other white space probably
* indicate a transmission error , about which a warning
* message or even a message rejection might be appropriate
* under some circumstances . " */
const xmlChar * cur = value ;
xmlChar * base ;
int total , i = 0 , pad = 0 ;
if ( cur = = NULL )
goto return1 ;
for ( ; * cur ; + + cur ) {
int decc ;
decc = _xmlSchemaBase64Decode ( * cur ) ;
if ( decc < 0 ) ;
else if ( decc < 64 )
i + + ;
else
break ;
}
for ( ; * cur ; + + cur ) {
int decc ;
decc = _xmlSchemaBase64Decode ( * cur ) ;
if ( decc < 0 ) ;
else if ( decc < 64 )
goto return1 ;
if ( decc = = 64 )
pad + + ;
}
/* rfc2045.txt: "Special processing is performed if fewer than
* 24 bits are available at the end of the data being encoded .
* A full encoding quantum is always completed at the end of a
* body . When fewer than 24 input bits are available in an
* input group , zero bits are added ( on the right ) to form an
* integral number of 6 - bit groups . Padding at the end of the
* data is performed using the " = " character . Since all
* base64 input is an integral number of octets , only the
* following cases can arise : ( 1 ) the final quantum of
* encoding input is an integral multiple of 24 bits ; here ,
* the final unit of encoded output will be an integral
2019-09-30 18:04:54 +03:00
* multiple of indent : Standard input : 701 : Warning : old style
2003-08-27 18:15:15 +04:00
* assignment ambiguity in " =* " . Assuming " = * " 4 characters
* with no " = " padding , ( 2 ) the final
* quantum of encoding input is exactly 8 bits ; here , the
* final unit of encoded output will be two characters
* followed by two " = " padding characters , or ( 3 ) the final
* quantum of encoding input is exactly 16 bits ; here , the
* final unit of encoded output will be three characters
* followed by one " = " padding character . " */
total = 3 * ( i / 4 ) ;
if ( pad = = 0 ) {
if ( i % 4 ! = 0 )
goto return1 ;
} else if ( pad = = 1 ) {
int decc ;
if ( i % 4 ! = 3 )
goto return1 ;
for ( decc = _xmlSchemaBase64Decode ( * cur ) ;
( decc < 0 ) | | ( decc > 63 ) ;
decc = _xmlSchemaBase64Decode ( * cur ) )
- - cur ;
/* 16bits in 24bits means 2 pad bits: nnnnnn nnmmmm mmmm00*/
/* 00111100 -> 0x3c */
if ( decc & ~ 0x3c )
goto return1 ;
total + = 2 ;
} else if ( pad = = 2 ) {
int decc ;
if ( i % 4 ! = 2 )
goto return1 ;
for ( decc = _xmlSchemaBase64Decode ( * cur ) ;
( decc < 0 ) | | ( decc > 63 ) ;
decc = _xmlSchemaBase64Decode ( * cur ) )
- - cur ;
/* 8bits in 12bits means 4 pad bits: nnnnnn nn0000 */
/* 00110000 -> 0x30 */
if ( decc & ~ 0x30 )
goto return1 ;
total + = 1 ;
} else
goto return1 ;
if ( val ! = NULL ) {
v = xmlSchemaNewValue ( XML_SCHEMAS_BASE64BINARY ) ;
if ( v = = NULL )
goto error ;
base =
2022-09-01 04:14:13 +03:00
( xmlChar * ) xmlMallocAtomic ( i + pad + 1 ) ;
2003-08-27 18:15:15 +04:00
if ( base = = NULL ) {
2023-12-18 21:51:32 +03:00
xmlSchemaTypeErrMemory ( ) ;
2003-08-27 18:15:15 +04:00
xmlFree ( v ) ;
goto return1 ;
}
v - > value . base64 . str = base ;
for ( cur = value ; * cur ; + + cur )
if ( _xmlSchemaBase64Decode ( * cur ) > = 0 ) {
* base = * cur ;
+ + base ;
}
* base = 0 ;
v - > value . base64 . total = total ;
* val = v ;
}
goto return0 ;
2003-08-08 18:00:28 +04:00
}
2003-03-31 01:10:09 +04:00
case XML_SCHEMAS_INTEGER :
case XML_SCHEMAS_PINTEGER :
case XML_SCHEMAS_NPINTEGER :
case XML_SCHEMAS_NINTEGER :
2023-11-07 23:08:01 +03:00
case XML_SCHEMAS_NNINTEGER :
2003-03-31 01:10:09 +04:00
case XML_SCHEMAS_LONG :
case XML_SCHEMAS_BYTE :
case XML_SCHEMAS_SHORT :
2023-11-07 23:08:01 +03:00
case XML_SCHEMAS_INT :
case XML_SCHEMAS_UINT :
case XML_SCHEMAS_ULONG :
case XML_SCHEMAS_USHORT :
case XML_SCHEMAS_UBYTE : {
2008-04-03 14:43:52 +04:00
const xmlChar * cur = value ;
2023-11-07 23:08:01 +03:00
xmlSchemaValDecimal decimal ;
xmlChar sign = ' + ' ;
memset ( & decimal , 0 , sizeof ( decimal ) ) ;
2003-08-27 18:15:15 +04:00
if ( cur = = NULL )
goto return1 ;
2023-11-07 23:08:01 +03:00
if ( normOnTheFly )
2021-08-19 03:46:32 +03:00
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2003-08-27 18:15:15 +04:00
if ( * cur = = ' - ' ) {
2023-11-07 23:08:01 +03:00
sign = ' - ' ;
2003-08-27 18:15:15 +04:00
cur + + ;
} else if ( * cur = = ' + ' )
cur + + ;
2023-11-07 23:08:01 +03:00
ret = xmlSchemaParseUInt ( & cur , & decimal ) ;
/* add sign */
2005-03-15 18:50:17 +03:00
if ( ret < 0 )
2023-11-07 23:08:01 +03:00
goto valIntegerReturn1 ;
decimal . str [ 0 ] = sign ;
2021-08-19 03:46:32 +03:00
if ( normOnTheFly )
while IS_WSP_BLANK_CH ( * cur ) cur + + ;
2005-03-15 18:50:17 +03:00
if ( * cur ! = 0 )
2023-11-07 23:08:01 +03:00
goto valIntegerReturn1 ;
if ( type - > builtInType = = XML_SCHEMAS_NPINTEGER )
{
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0 ) > 0 )
goto valIntegerReturn1 ;
2003-08-27 18:15:15 +04:00
}
2023-11-07 23:08:01 +03:00
else if ( type - > builtInType = = XML_SCHEMAS_PINTEGER )
{
if ( sign = = ' - ' )
goto valIntegerReturn1 ;
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0 ) < = 0 )
goto valIntegerReturn1 ;
2003-08-27 18:15:15 +04:00
}
2023-11-07 23:08:01 +03:00
else if ( type - > builtInType = = XML_SCHEMAS_NINTEGER )
{
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0 ) > = 0 )
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_NNINTEGER )
{
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0 ) < 0 )
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_LONG )
{
/* (u)int64_t may not be available on 32 bit platform, just use decimal */
xmlSchemaValDecimal tmpDecimal ;
static const char maxLong [ ] = " +9223372036854775807.0 " ;
static const char minLong [ ] = " -9223372036854775808.0 " ;
tmpDecimal . fractionalPlaces = 1 ;
tmpDecimal . integralPlaces = 19 ;
tmpDecimal . str = BAD_CAST maxLong ;
if ( xmlSchemaValDecimalCompare ( & decimal , & tmpDecimal ) > 0 )
goto valIntegerReturn1 ;
tmpDecimal . str = BAD_CAST minLong ;
if ( xmlSchemaValDecimalCompare ( & decimal , & tmpDecimal ) < 0 )
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_ULONG )
{
xmlSchemaValDecimal tmpDecimal ;
static const char maxULong [ ] = " +18446744073709551615.0 " ;
tmpDecimal . fractionalPlaces = 1 ;
tmpDecimal . integralPlaces = 20 ;
tmpDecimal . str = ( xmlChar * ) maxULong ;
if ( xmlSchemaValDecimalCompare ( & decimal , & tmpDecimal ) > 0 )
goto valIntegerReturn1 ;
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0 ) < 0 )
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_INT )
{
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0x7fffffff ) > 0 ) /* INT32_MAX */
goto valIntegerReturn1 ;
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , - 0x7fffffff - 1 ) < 0 ) /* INT32_MIN */
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_SHORT )
{
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0x7fff ) > 0 ) /* INT16_MAX */
goto valIntegerReturn1 ;
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , - 0x8000 ) < 0 ) /* INT16_MIN */
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_BYTE )
{ if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0x7f ) > 0 ) /* INT8_MAX */
goto valIntegerReturn1 ;
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , - 0x80 ) < 0 ) /* INT8_MIN */
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_UINT )
{
xmlSchemaValDecimal tmpDecimal ;
static const char maxUInt [ ] = " +4294967295.0 " ;
tmpDecimal . fractionalPlaces = 1 ;
tmpDecimal . integralPlaces = 10 ;
tmpDecimal . str = ( xmlChar * ) maxUInt ;
if ( xmlSchemaValDecimalCompare ( & decimal , & tmpDecimal ) > 0 )
goto valIntegerReturn1 ;
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0 ) < 0 )
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_USHORT )
{
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0xffff ) > 0 ) /* UINT16_MAX */
goto valIntegerReturn1 ;
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0 ) < 0 )
goto valIntegerReturn1 ;
}
else if ( type - > builtInType = = XML_SCHEMAS_UBYTE )
{
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0xff ) > 0 ) /* UINT8_MAX */
goto valIntegerReturn1 ;
if ( xmlSchemaValDecimalCompareWithInteger ( & decimal , 0 ) < 0 )
goto valIntegerReturn1 ;
2003-08-27 18:15:15 +04:00
}
if ( val ! = NULL ) {
2004-06-29 21:04:39 +04:00
v = xmlSchemaNewValue ( type - > builtInType ) ;
2003-08-27 18:15:15 +04:00
if ( v ! = NULL ) {
2023-11-07 23:08:01 +03:00
v - > value . decimal = decimal ;
2003-08-27 18:15:15 +04:00
* val = v ;
}
}
2023-11-07 23:08:01 +03:00
else if ( decimal . str ! = NULL )
{
xmlFree ( decimal . str ) ;
}
2003-08-27 18:15:15 +04:00
goto return0 ;
2023-11-07 23:08:01 +03:00
valIntegerReturn1 :
if ( decimal . str ! = NULL )
{
xmlFree ( decimal . str ) ;
}
goto return1 ;
2003-08-27 18:15:15 +04:00
}
2002-04-16 19:50:10 +04:00
}
2003-03-29 19:41:55 +03:00
2003-08-27 18:15:15 +04:00
done :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( ret ) ;
return3 :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( 3 ) ;
return1 :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( 1 ) ;
return0 :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( 0 ) ;
error :
if ( norm ! = NULL )
xmlFree ( norm ) ;
return ( - 1 ) ;
2003-03-29 19:41:55 +03:00
}
/**
* xmlSchemaValPredefTypeNode :
* @ type : the predefined type
* @ value : the value to check
* @ val : the return computed value
* @ node : the node containing the value
*
* Check that a value conforms to the lexical space of the predefined type .
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
int
xmlSchemaValPredefTypeNode ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * val , xmlNodePtr node ) {
2005-06-09 14:32:53 +04:00
return ( xmlSchemaValAtomicType ( type , value , val , node , 0 ,
XML_SCHEMA_WHITESPACE_UNKNOWN , 1 , 1 , 0 ) ) ;
2002-04-16 19:50:10 +04:00
}
2004-08-10 18:17:33 +04:00
/**
* xmlSchemaValPredefTypeNodeNoNorm :
* @ type : the predefined type
* @ value : the value to check
* @ val : the return computed value
* @ node : the node containing the value
*
* Check that a value conforms to the lexical space of the predefined type .
* if true a value is computed and returned in @ val .
* This one does apply any normalization to the value .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
int
xmlSchemaValPredefTypeNodeNoNorm ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * val , xmlNodePtr node ) {
2005-06-09 14:32:53 +04:00
return ( xmlSchemaValAtomicType ( type , value , val , node , 1 ,
XML_SCHEMA_WHITESPACE_UNKNOWN , 1 , 0 , 1 ) ) ;
2004-08-10 18:17:33 +04:00
}
2003-03-18 03:31:04 +03:00
/**
* xmlSchemaValidatePredefinedType :
* @ type : the predefined type
* @ value : the value to check
* @ val : the return computed value
*
* Check that a value conforms to the lexical space of the predefined type .
* if true a value is computed and returned in @ val .
*
* Returns 0 if this validates , a positive error code number otherwise
* and - 1 in case of internal or API error .
*/
int
xmlSchemaValidatePredefinedType ( xmlSchemaTypePtr type , const xmlChar * value ,
xmlSchemaValPtr * val ) {
return ( xmlSchemaValPredefTypeNode ( type , value , val , NULL ) ) ;
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaCompareDecimals :
* @ x : a first decimal value
* @ y : a second decimal value
*
* Compare 2 decimals
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y and - 2 in case of error
*/
static int
xmlSchemaCompareDecimals ( xmlSchemaValPtr x , xmlSchemaValPtr y )
{
2023-11-07 23:08:01 +03:00
int res = xmlSchemaValDecimalCompare ( & x - > value . decimal , & y - > value . decimal ) ;
if ( res > 0 )
{
return 1 ;
2005-03-11 18:55:14 +03:00
}
2023-11-07 23:08:01 +03:00
if ( res < 0 )
{
return - 1 ;
2002-04-16 19:50:10 +04:00
}
2023-11-07 23:08:01 +03:00
return 0 ;
2002-04-16 19:50:10 +04:00
}
2002-05-03 11:29:38 +04:00
/**
* xmlSchemaCompareDurations :
* @ x : a first duration value
* @ y : a second duration value
*
* Compare 2 durations
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
static int
xmlSchemaCompareDurations ( xmlSchemaValPtr x , xmlSchemaValPtr y )
{
long carry , mon , day ;
double sec ;
2003-03-28 16:29:53 +03:00
int invert = 1 ;
long xmon , xday , myear , minday , maxday ;
2002-05-03 11:29:38 +04:00
static const long dayRange [ 2 ] [ 12 ] = {
{ 0 , 28 , 59 , 89 , 120 , 150 , 181 , 212 , 242 , 273 , 303 , 334 , } ,
{ 0 , 31 , 62 , 92 , 123 , 153 , 184 , 215 , 245 , 276 , 306 , 337 } } ;
if ( ( x = = NULL ) | | ( y = = NULL ) )
2002-05-22 10:40:27 +04:00
return - 2 ;
2002-05-03 11:29:38 +04:00
/* months */
mon = x - > value . dur . mon - y - > value . dur . mon ;
/* seconds */
sec = x - > value . dur . sec - y - > value . dur . sec ;
2011-11-10 19:23:10 +04:00
carry = ( long ) ( sec / SECS_PER_DAY ) ;
sec - = ( ( double ) carry ) * SECS_PER_DAY ;
2002-05-03 11:29:38 +04:00
/* days */
day = x - > value . dur . day - y - > value . dur . day + carry ;
/* easy test */
if ( mon = = 0 ) {
if ( day = = 0 )
if ( sec = = 0.0 )
return 0 ;
else if ( sec < 0.0 )
return - 1 ;
else
return 1 ;
else if ( day < 0 )
return - 1 ;
else
return 1 ;
}
if ( mon > 0 ) {
if ( ( day > = 0 ) & & ( sec > = 0.0 ) )
return 1 ;
else {
xmon = mon ;
xday = - day ;
}
} else if ( ( day < = 0 ) & & ( sec < = 0.0 ) ) {
return - 1 ;
} else {
2003-03-28 16:29:53 +03:00
invert = - 1 ;
2002-05-03 11:29:38 +04:00
xmon = - mon ;
xday = day ;
}
myear = xmon / 12 ;
2003-03-28 16:29:53 +03:00
if ( myear = = 0 ) {
minday = 0 ;
maxday = 0 ;
} else {
2020-08-03 18:30:41 +03:00
if ( myear > LONG_MAX / 366 )
return - 2 ;
2019-08-25 15:12:23 +03:00
/* FIXME: This doesn't take leap year exceptions every 100/400 years
into account . */
maxday = 365 * myear + ( myear + 3 ) / 4 ;
/* FIXME: Needs to be calculated separately */
2003-03-28 16:29:53 +03:00
minday = maxday - 1 ;
}
2002-05-03 11:29:38 +04:00
xmon = xmon % 12 ;
minday + = dayRange [ 0 ] [ xmon ] ;
maxday + = dayRange [ 1 ] [ xmon ] ;
2003-03-28 16:29:53 +03:00
if ( ( maxday = = minday ) & & ( maxday = = xday ) )
return ( 0 ) ; /* can this really happen ? */
2002-05-03 11:29:38 +04:00
if ( maxday < xday )
2003-03-28 16:29:53 +03:00
return ( - invert ) ;
if ( minday > xday )
return ( invert ) ;
2002-05-03 11:29:38 +04:00
/* indeterminate */
2002-05-22 10:40:27 +04:00
return 2 ;
}
/*
* macros for adding date / times and durations
*/
# define FQUOTIENT(a,b) (floor(((double)a / (double)b)))
# define MODULO(a,b) (a - FQUOTIENT(a,b) * b)
# define FQUOTIENT_RANGE(a,low,high) (FQUOTIENT((a-low),(high-low)))
# define MODULO_RANGE(a,low,high) ((MODULO((a-low),(high-low)))+low)
2004-05-30 00:12:46 +04:00
/**
* xmlSchemaDupVal :
* @ v : the # xmlSchemaValPtr value to duplicate
*
* Makes a copy of @ v . The calling program is responsible for freeing
* the returned value .
*
* returns a pointer to a duplicated # xmlSchemaValPtr or NULL if error .
*/
static xmlSchemaValPtr
xmlSchemaDupVal ( xmlSchemaValPtr v )
{
xmlSchemaValPtr ret = xmlSchemaNewValue ( v - > type ) ;
if ( ret = = NULL )
return NULL ;
2012-09-11 09:26:36 +04:00
2004-05-30 00:12:46 +04:00
memcpy ( ret , v , sizeof ( xmlSchemaVal ) ) ;
2005-06-09 14:32:53 +04:00
ret - > next = NULL ;
2004-05-30 00:12:46 +04:00
return ret ;
}
2005-03-04 21:04:59 +03:00
/**
* xmlSchemaCopyValue :
* @ val : the precomputed value to be copied
*
* Copies the precomputed value . This duplicates any string within .
*
* Returns the copy or NULL if a copy for a data - type is not implemented .
*/
xmlSchemaValPtr
xmlSchemaCopyValue ( xmlSchemaValPtr val )
{
2005-06-09 14:32:53 +04:00
xmlSchemaValPtr ret = NULL , prev = NULL , cur ;
2005-03-04 21:04:59 +03:00
/*
* Copy the string values .
*/
2005-06-09 14:32:53 +04:00
while ( val ! = NULL ) {
switch ( val - > type ) {
case XML_SCHEMAS_ANYTYPE :
case XML_SCHEMAS_IDREFS :
case XML_SCHEMAS_ENTITIES :
case XML_SCHEMAS_NMTOKENS :
xmlSchemaFreeValue ( ret ) ;
return ( NULL ) ;
case XML_SCHEMAS_ANYSIMPLETYPE :
case XML_SCHEMAS_STRING :
case XML_SCHEMAS_NORMSTRING :
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_ENTITY :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_ANYURI :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . str ! = NULL )
cur - > value . str = xmlStrdup ( BAD_CAST val - > value . str ) ;
break ;
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_QNAME :
2005-06-09 14:32:53 +04:00
case XML_SCHEMAS_NOTATION :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . qname . name ! = NULL )
cur - > value . qname . name =
2005-03-04 21:04:59 +03:00
xmlStrdup ( BAD_CAST val - > value . qname . name ) ;
2005-06-09 14:32:53 +04:00
if ( val - > value . qname . uri ! = NULL )
cur - > value . qname . uri =
2005-03-04 21:04:59 +03:00
xmlStrdup ( BAD_CAST val - > value . qname . uri ) ;
2005-06-09 14:32:53 +04:00
break ;
case XML_SCHEMAS_HEXBINARY :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . hex . str ! = NULL )
cur - > value . hex . str = xmlStrdup ( BAD_CAST val - > value . hex . str ) ;
break ;
case XML_SCHEMAS_BASE64BINARY :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . base64 . str ! = NULL )
cur - > value . base64 . str =
2005-03-04 21:04:59 +03:00
xmlStrdup ( BAD_CAST val - > value . base64 . str ) ;
2005-06-09 14:32:53 +04:00
break ;
2023-11-07 23:08:01 +03:00
case XML_SCHEMAS_DECIMAL :
case XML_SCHEMAS_INTEGER :
case XML_SCHEMAS_PINTEGER :
case XML_SCHEMAS_NPINTEGER :
case XML_SCHEMAS_NINTEGER :
case XML_SCHEMAS_NNINTEGER :
case XML_SCHEMAS_LONG :
case XML_SCHEMAS_BYTE :
case XML_SCHEMAS_SHORT :
case XML_SCHEMAS_INT :
case XML_SCHEMAS_UINT :
case XML_SCHEMAS_ULONG :
case XML_SCHEMAS_USHORT :
case XML_SCHEMAS_UBYTE :
cur = xmlSchemaDupVal ( val ) ;
if ( val - > value . decimal . str ! = NULL )
cur - > value . decimal . str = xmlStrdup ( BAD_CAST val - > value . decimal . str ) ;
break ;
2005-06-09 14:32:53 +04:00
default :
cur = xmlSchemaDupVal ( val ) ;
break ;
}
if ( ret = = NULL )
ret = cur ;
else
prev - > next = cur ;
prev = cur ;
val = val - > next ;
2005-03-04 21:04:59 +03:00
}
2005-06-09 14:32:53 +04:00
return ( ret ) ;
2005-03-04 21:04:59 +03:00
}
2002-05-22 10:40:27 +04:00
/**
* _xmlSchemaDateAdd :
* @ dt : an # xmlSchemaValPtr
* @ dur : an # xmlSchemaValPtr of type # XS_DURATION
*
* Compute a new date / time from @ dt and @ dur . This function assumes @ dt
* is either # XML_SCHEMAS_DATETIME , # XML_SCHEMAS_DATE , # XML_SCHEMAS_GYEARMONTH ,
2004-05-30 00:12:46 +04:00
* or # XML_SCHEMAS_GYEAR . The returned # xmlSchemaVal is the same type as
* @ dt . The calling program is responsible for freeing the returned value .
2002-05-22 10:40:27 +04:00
*
2004-05-30 00:12:46 +04:00
* Returns a pointer to a new # xmlSchemaVal or NULL if error .
2002-05-22 10:40:27 +04:00
*/
static xmlSchemaValPtr
_xmlSchemaDateAdd ( xmlSchemaValPtr dt , xmlSchemaValPtr dur )
{
2004-05-30 00:12:46 +04:00
xmlSchemaValPtr ret , tmp ;
2002-05-22 10:40:27 +04:00
long carry , tempdays , temp ;
xmlSchemaValDatePtr r , d ;
xmlSchemaValDurationPtr u ;
if ( ( dt = = NULL ) | | ( dur = = NULL ) )
return NULL ;
ret = xmlSchemaNewValue ( dt - > type ) ;
if ( ret = = NULL )
return NULL ;
2004-05-30 00:12:46 +04:00
/* make a copy so we don't alter the original value */
tmp = xmlSchemaDupVal ( dt ) ;
if ( tmp = = NULL ) {
xmlSchemaFreeValue ( ret ) ;
return NULL ;
}
2002-05-22 10:40:27 +04:00
r = & ( ret - > value . date ) ;
2004-05-30 00:12:46 +04:00
d = & ( tmp - > value . date ) ;
2002-05-22 10:40:27 +04:00
u = & ( dur - > value . dur ) ;
/* normalization */
if ( d - > mon = = 0 )
d - > mon = 1 ;
/* normalize for time zone offset */
u - > sec - = ( d - > tzo * 60 ) ;
d - > tzo = 0 ;
/* normalization */
if ( d - > day = = 0 )
d - > day = 1 ;
/* month */
carry = d - > mon + u - > mon ;
2004-03-25 12:35:49 +03:00
r - > mon = ( unsigned int ) MODULO_RANGE ( carry , 1 , 13 ) ;
carry = ( long ) FQUOTIENT_RANGE ( carry , 1 , 13 ) ;
2002-05-22 10:40:27 +04:00
/* year (may be modified later) */
r - > year = d - > year + carry ;
if ( r - > year = = 0 ) {
if ( d - > year > 0 )
r - > year - - ;
else
r - > year + + ;
}
/* time zone */
r - > tzo = d - > tzo ;
r - > tz_flag = d - > tz_flag ;
/* seconds */
r - > sec = d - > sec + u - > sec ;
2004-03-25 12:35:49 +03:00
carry = ( long ) FQUOTIENT ( ( long ) r - > sec , 60 ) ;
2002-05-22 10:40:27 +04:00
if ( r - > sec ! = 0.0 ) {
r - > sec = MODULO ( r - > sec , 60.0 ) ;
}
/* minute */
carry + = d - > min ;
2004-03-25 12:35:49 +03:00
r - > min = ( unsigned int ) MODULO ( carry , 60 ) ;
carry = ( long ) FQUOTIENT ( carry , 60 ) ;
2002-05-22 10:40:27 +04:00
/* hours */
carry + = d - > hour ;
2004-03-25 12:35:49 +03:00
r - > hour = ( unsigned int ) MODULO ( carry , 24 ) ;
carry = ( long ) FQUOTIENT ( carry , 24 ) ;
2002-05-22 10:40:27 +04:00
/*
* days
* Note we use tempdays because the temporary values may need more
* than 5 bits
*/
if ( ( VALID_YEAR ( r - > year ) ) & & ( VALID_MONTH ( r - > mon ) ) & &
( d - > day > MAX_DAYINMONTH ( r - > year , r - > mon ) ) )
tempdays = MAX_DAYINMONTH ( r - > year , r - > mon ) ;
else if ( d - > day < 1 )
tempdays = 1 ;
else
tempdays = d - > day ;
tempdays + = u - > day + carry ;
while ( 1 ) {
if ( tempdays < 1 ) {
2005-11-21 14:23:47 +03:00
long tmon = ( long ) MODULO_RANGE ( ( int ) r - > mon - 1 , 1 , 13 ) ;
long tyr = r - > year + ( long ) FQUOTIENT_RANGE ( ( int ) r - > mon - 1 , 1 , 13 ) ;
2002-05-22 10:40:27 +04:00
if ( tyr = = 0 )
tyr - - ;
2006-03-09 21:41:40 +03:00
/*
2012-09-11 09:26:36 +04:00
* Coverity detected an overrun in daysInMonth
2006-03-09 21:41:40 +03:00
* of size 12 at position 12 with index variable " ((r)->mon - 1) "
*/
2014-07-14 18:29:56 +04:00
if ( tmon < 1 )
tmon = 1 ;
2006-03-09 21:41:40 +03:00
if ( tmon > 12 )
tmon = 12 ;
2002-05-22 10:40:27 +04:00
tempdays + = MAX_DAYINMONTH ( tyr , tmon ) ;
carry = - 1 ;
2014-06-21 00:37:21 +04:00
} else if ( VALID_YEAR ( r - > year ) & & VALID_MONTH ( r - > mon ) & &
tempdays > ( long ) MAX_DAYINMONTH ( r - > year , r - > mon ) ) {
2002-05-22 10:40:27 +04:00
tempdays = tempdays - MAX_DAYINMONTH ( r - > year , r - > mon ) ;
carry = 1 ;
} else
break ;
temp = r - > mon + carry ;
2004-03-25 12:35:49 +03:00
r - > mon = ( unsigned int ) MODULO_RANGE ( temp , 1 , 13 ) ;
2019-05-21 14:21:29 +03:00
r - > year = r - > year + ( long ) FQUOTIENT_RANGE ( temp , 1 , 13 ) ;
2002-05-22 10:40:27 +04:00
if ( r - > year = = 0 ) {
if ( temp < 1 )
r - > year - - ;
else
r - > year + + ;
}
}
2012-09-11 09:26:36 +04:00
2002-05-22 10:40:27 +04:00
r - > day = tempdays ;
/*
* adjust the date / time type to the date values
*/
if ( ret - > type ! = XML_SCHEMAS_DATETIME ) {
if ( ( r - > hour ) | | ( r - > min ) | | ( r - > sec ) )
ret - > type = XML_SCHEMAS_DATETIME ;
else if ( ret - > type ! = XML_SCHEMAS_DATE ) {
if ( ( r - > mon ! = 1 ) & & ( r - > day ! = 1 ) )
ret - > type = XML_SCHEMAS_DATE ;
else if ( ( ret - > type ! = XML_SCHEMAS_GYEARMONTH ) & & ( r - > mon ! = 1 ) )
ret - > type = XML_SCHEMAS_GYEARMONTH ;
}
}
2004-05-30 00:12:46 +04:00
xmlSchemaFreeValue ( tmp ) ;
2002-05-22 10:40:27 +04:00
return ret ;
}
/**
* xmlSchemaDateNormalize :
2004-05-30 00:12:46 +04:00
* @ dt : an # xmlSchemaValPtr of a date / time type value .
* @ offset : number of seconds to adjust @ dt by .
2002-05-22 10:40:27 +04:00
*
2004-05-30 00:12:46 +04:00
* Normalize @ dt to GMT time . The @ offset parameter is subtracted from
* the return value is a time - zone offset is present on @ dt .
2002-05-22 10:40:27 +04:00
*
2004-05-30 00:12:46 +04:00
* Returns a normalized copy of @ dt or NULL if error .
2002-05-22 10:40:27 +04:00
*/
static xmlSchemaValPtr
xmlSchemaDateNormalize ( xmlSchemaValPtr dt , double offset )
{
xmlSchemaValPtr dur , ret ;
if ( dt = = NULL )
return NULL ;
if ( ( ( dt - > type ! = XML_SCHEMAS_TIME ) & &
2005-04-18 14:57:04 +04:00
( dt - > type ! = XML_SCHEMAS_DATETIME ) & &
( dt - > type ! = XML_SCHEMAS_DATE ) ) | | ( dt - > value . date . tzo = = 0 ) )
2002-05-22 10:40:27 +04:00
return xmlSchemaDupVal ( dt ) ;
dur = xmlSchemaNewValue ( XML_SCHEMAS_DURATION ) ;
if ( dur = = NULL )
return NULL ;
dur - > value . date . sec - = offset ;
ret = _xmlSchemaDateAdd ( dt , dur ) ;
if ( ret = = NULL )
return NULL ;
xmlSchemaFreeValue ( dur ) ;
/* ret->value.date.tzo = 0; */
return ret ;
}
/**
* _xmlSchemaDateCastYMToDays :
* @ dt : an # xmlSchemaValPtr
*
2012-09-11 09:26:36 +04:00
* Convert mon and year of @ dt to total number of days . Take the
2002-05-22 10:40:27 +04:00
* number of years since ( or before ) 1 AD and add the number of leap
* years . This is a function because negative
* years must be handled a little differently and there is no zero year .
*
* Returns number of days .
*/
static long
_xmlSchemaDateCastYMToDays ( const xmlSchemaValPtr dt )
{
long ret ;
2004-09-23 20:24:36 +04:00
int mon ;
2002-05-22 10:40:27 +04:00
2004-09-23 20:24:36 +04:00
mon = dt - > value . date . mon ;
if ( mon < = 0 ) mon = 1 ; /* normalization */
if ( dt - > value . date . year < = 0 )
2002-05-22 10:40:27 +04:00
ret = ( dt - > value . date . year * 365 ) +
( ( ( dt - > value . date . year + 1 ) / 4 ) - ( ( dt - > value . date . year + 1 ) / 100 ) +
( ( dt - > value . date . year + 1 ) / 400 ) ) +
2004-09-23 20:24:36 +04:00
DAY_IN_YEAR ( 0 , mon , dt - > value . date . year ) ;
2002-05-22 10:40:27 +04:00
else
ret = ( ( dt - > value . date . year - 1 ) * 365 ) +
( ( ( dt - > value . date . year - 1 ) / 4 ) - ( ( dt - > value . date . year - 1 ) / 100 ) +
( ( dt - > value . date . year - 1 ) / 400 ) ) +
2004-09-23 20:24:36 +04:00
DAY_IN_YEAR ( 0 , mon , dt - > value . date . year ) ;
2002-05-22 10:40:27 +04:00
return ret ;
}
/**
* TIME_TO_NUMBER :
* @ dt : an # xmlSchemaValPtr
*
* Calculates the number of seconds in the time portion of @ dt .
*
* Returns seconds .
*/
# define TIME_TO_NUMBER(dt) \
( ( double ) ( ( dt - > value . date . hour * SECS_PER_HOUR ) + \
2003-03-31 15:22:25 +04:00
( dt - > value . date . min * SECS_PER_MIN ) + \
( dt - > value . date . tzo * SECS_PER_MIN ) ) + \
dt - > value . date . sec )
2002-05-22 10:40:27 +04:00
/**
* xmlSchemaCompareDates :
* @ x : a first date / time value
* @ y : a second date / time value
*
* Compare 2 date / times
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
static int
xmlSchemaCompareDates ( xmlSchemaValPtr x , xmlSchemaValPtr y )
{
unsigned char xmask , ymask , xor_mask , and_mask ;
xmlSchemaValPtr p1 , p2 , q1 , q2 ;
long p1d , p2d , q1d , q2d ;
if ( ( x = = NULL ) | | ( y = = NULL ) )
return - 2 ;
2020-08-03 18:30:41 +03:00
if ( ( x - > value . date . year > LONG_MAX / 366 ) | |
( x - > value . date . year < LONG_MIN / 366 ) | |
( y - > value . date . year > LONG_MAX / 366 ) | |
( y - > value . date . year < LONG_MIN / 366 ) ) {
/* Possible overflow when converting to days. */
return - 2 ;
}
2002-05-22 10:40:27 +04:00
if ( x - > value . date . tz_flag ) {
if ( ! y - > value . date . tz_flag ) {
p1 = xmlSchemaDateNormalize ( x , 0 ) ;
2023-03-05 16:10:56 +03:00
if ( p1 = = NULL )
return - 2 ;
2002-05-22 10:40:27 +04:00
p1d = _xmlSchemaDateCastYMToDays ( p1 ) + p1 - > value . date . day ;
/* normalize y + 14:00 */
q1 = xmlSchemaDateNormalize ( y , ( 14 * SECS_PER_HOUR ) ) ;
2023-03-05 16:10:56 +03:00
if ( q1 = = NULL ) {
xmlSchemaFreeValue ( p1 ) ;
return - 2 ;
}
2002-05-22 10:40:27 +04:00
q1d = _xmlSchemaDateCastYMToDays ( q1 ) + q1 - > value . date . day ;
2002-07-02 01:52:03 +04:00
if ( p1d < q1d ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 10:40:27 +04:00
return - 1 ;
2002-07-02 01:52:03 +04:00
} else if ( p1d = = q1d ) {
2002-05-22 10:40:27 +04:00
double sec ;
sec = TIME_TO_NUMBER ( p1 ) - TIME_TO_NUMBER ( q1 ) ;
2002-07-02 01:52:03 +04:00
if ( sec < 0.0 ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 10:40:27 +04:00
return - 1 ;
2002-07-02 01:52:03 +04:00
} else {
2003-10-17 16:43:59 +04:00
int ret = 0 ;
2002-05-22 10:40:27 +04:00
/* normalize y - 14:00 */
q2 = xmlSchemaDateNormalize ( y , - ( 14 * SECS_PER_HOUR ) ) ;
2023-03-05 16:10:56 +03:00
if ( q2 = = NULL ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
return - 2 ;
}
2002-05-22 10:40:27 +04:00
q2d = _xmlSchemaDateCastYMToDays ( q2 ) + q2 - > value . date . day ;
if ( p1d > q2d )
2003-10-17 16:43:59 +04:00
ret = 1 ;
2002-05-22 10:40:27 +04:00
else if ( p1d = = q2d ) {
sec = TIME_TO_NUMBER ( p1 ) - TIME_TO_NUMBER ( q2 ) ;
if ( sec > 0.0 )
2003-10-17 16:43:59 +04:00
ret = 1 ;
2002-05-22 10:40:27 +04:00
else
2003-10-17 16:43:59 +04:00
ret = 2 ; /* indeterminate */
2002-05-22 10:40:27 +04:00
}
2003-10-17 16:43:59 +04:00
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
xmlSchemaFreeValue ( q2 ) ;
if ( ret ! = 0 )
return ( ret ) ;
2002-05-22 10:40:27 +04:00
}
2002-07-02 01:52:03 +04:00
} else {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
}
2002-05-22 10:40:27 +04:00
}
} else if ( y - > value . date . tz_flag ) {
q1 = xmlSchemaDateNormalize ( y , 0 ) ;
2023-03-05 16:10:56 +03:00
if ( q1 = = NULL )
return - 2 ;
2002-05-22 10:40:27 +04:00
q1d = _xmlSchemaDateCastYMToDays ( q1 ) + q1 - > value . date . day ;
/* normalize x - 14:00 */
p1 = xmlSchemaDateNormalize ( x , - ( 14 * SECS_PER_HOUR ) ) ;
2023-03-05 16:10:56 +03:00
if ( p1 = = NULL ) {
xmlSchemaFreeValue ( q1 ) ;
return - 2 ;
}
2002-05-22 10:40:27 +04:00
p1d = _xmlSchemaDateCastYMToDays ( p1 ) + p1 - > value . date . day ;
2002-07-02 01:52:03 +04:00
if ( p1d < q1d ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 10:40:27 +04:00
return - 1 ;
2002-07-02 01:52:03 +04:00
} else if ( p1d = = q1d ) {
2002-05-22 10:40:27 +04:00
double sec ;
sec = TIME_TO_NUMBER ( p1 ) - TIME_TO_NUMBER ( q1 ) ;
2002-07-02 01:52:03 +04:00
if ( sec < 0.0 ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 10:40:27 +04:00
return - 1 ;
2002-07-02 01:52:03 +04:00
} else {
2003-10-17 16:43:59 +04:00
int ret = 0 ;
2002-05-22 10:40:27 +04:00
/* normalize x + 14:00 */
p2 = xmlSchemaDateNormalize ( x , ( 14 * SECS_PER_HOUR ) ) ;
2023-03-05 16:10:56 +03:00
if ( p2 = = NULL ) {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
return - 2 ;
}
2002-05-22 10:40:27 +04:00
p2d = _xmlSchemaDateCastYMToDays ( p2 ) + p2 - > value . date . day ;
2003-03-28 00:25:38 +03:00
if ( p2d > q1d ) {
2003-10-17 16:43:59 +04:00
ret = 1 ;
2003-03-28 00:25:38 +03:00
} else if ( p2d = = q1d ) {
2002-05-22 10:40:27 +04:00
sec = TIME_TO_NUMBER ( p2 ) - TIME_TO_NUMBER ( q1 ) ;
if ( sec > 0.0 )
2003-10-17 16:43:59 +04:00
ret = 1 ;
2002-05-22 10:40:27 +04:00
else
2003-10-17 16:43:59 +04:00
ret = 2 ; /* indeterminate */
2002-05-22 10:40:27 +04:00
}
2003-03-28 00:25:38 +03:00
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
xmlSchemaFreeValue ( p2 ) ;
2003-10-17 16:43:59 +04:00
if ( ret ! = 0 )
return ( ret ) ;
2002-05-22 10:40:27 +04:00
}
2002-07-02 01:52:03 +04:00
} else {
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
2002-05-22 10:40:27 +04:00
}
}
/*
* if the same type then calculate the difference
*/
if ( x - > type = = y - > type ) {
2003-10-17 16:43:59 +04:00
int ret = 0 ;
2002-05-22 10:40:27 +04:00
q1 = xmlSchemaDateNormalize ( y , 0 ) ;
2023-03-05 16:10:56 +03:00
if ( q1 = = NULL )
return - 2 ;
2002-05-22 10:40:27 +04:00
q1d = _xmlSchemaDateCastYMToDays ( q1 ) + q1 - > value . date . day ;
p1 = xmlSchemaDateNormalize ( x , 0 ) ;
2023-03-05 16:10:56 +03:00
if ( p1 = = NULL ) {
xmlSchemaFreeValue ( q1 ) ;
return - 2 ;
}
2002-05-22 10:40:27 +04:00
p1d = _xmlSchemaDateCastYMToDays ( p1 ) + p1 - > value . date . day ;
2002-07-02 01:52:03 +04:00
if ( p1d < q1d ) {
2003-10-17 16:43:59 +04:00
ret = - 1 ;
2002-07-02 01:52:03 +04:00
} else if ( p1d > q1d ) {
2003-10-17 16:43:59 +04:00
ret = 1 ;
2002-07-02 01:52:03 +04:00
} else {
2002-05-22 10:40:27 +04:00
double sec ;
sec = TIME_TO_NUMBER ( p1 ) - TIME_TO_NUMBER ( q1 ) ;
if ( sec < 0.0 )
2003-10-17 16:43:59 +04:00
ret = - 1 ;
2002-05-22 10:40:27 +04:00
else if ( sec > 0.0 )
2003-10-17 16:43:59 +04:00
ret = 1 ;
2012-09-11 09:26:36 +04:00
2002-05-22 10:40:27 +04:00
}
2003-10-17 16:43:59 +04:00
xmlSchemaFreeValue ( p1 ) ;
xmlSchemaFreeValue ( q1 ) ;
return ( ret ) ;
2002-05-22 10:40:27 +04:00
}
switch ( x - > type ) {
case XML_SCHEMAS_DATETIME :
xmask = 0xf ;
break ;
case XML_SCHEMAS_DATE :
xmask = 0x7 ;
break ;
case XML_SCHEMAS_GYEAR :
xmask = 0x1 ;
break ;
case XML_SCHEMAS_GMONTH :
xmask = 0x2 ;
break ;
case XML_SCHEMAS_GDAY :
xmask = 0x3 ;
break ;
case XML_SCHEMAS_GYEARMONTH :
xmask = 0x3 ;
break ;
case XML_SCHEMAS_GMONTHDAY :
xmask = 0x6 ;
break ;
case XML_SCHEMAS_TIME :
xmask = 0x8 ;
break ;
default :
xmask = 0 ;
break ;
}
switch ( y - > type ) {
case XML_SCHEMAS_DATETIME :
ymask = 0xf ;
break ;
case XML_SCHEMAS_DATE :
ymask = 0x7 ;
break ;
case XML_SCHEMAS_GYEAR :
ymask = 0x1 ;
break ;
case XML_SCHEMAS_GMONTH :
ymask = 0x2 ;
break ;
case XML_SCHEMAS_GDAY :
ymask = 0x3 ;
break ;
case XML_SCHEMAS_GYEARMONTH :
ymask = 0x3 ;
break ;
case XML_SCHEMAS_GMONTHDAY :
ymask = 0x6 ;
break ;
case XML_SCHEMAS_TIME :
ymask = 0x8 ;
break ;
default :
ymask = 0 ;
break ;
}
xor_mask = xmask ^ ymask ; /* mark type differences */
and_mask = xmask & ymask ; /* mark field specification */
/* year */
if ( xor_mask & 1 )
return 2 ; /* indeterminate */
else if ( and_mask & 1 ) {
if ( x - > value . date . year < y - > value . date . year )
return - 1 ;
else if ( x - > value . date . year > y - > value . date . year )
return 1 ;
}
/* month */
if ( xor_mask & 2 )
return 2 ; /* indeterminate */
else if ( and_mask & 2 ) {
if ( x - > value . date . mon < y - > value . date . mon )
return - 1 ;
else if ( x - > value . date . mon > y - > value . date . mon )
return 1 ;
}
/* day */
if ( xor_mask & 4 )
return 2 ; /* indeterminate */
else if ( and_mask & 4 ) {
if ( x - > value . date . day < y - > value . date . day )
return - 1 ;
else if ( x - > value . date . day > y - > value . date . day )
return 1 ;
}
/* time */
if ( xor_mask & 8 )
return 2 ; /* indeterminate */
else if ( and_mask & 8 ) {
if ( x - > value . date . hour < y - > value . date . hour )
return - 1 ;
else if ( x - > value . date . hour > y - > value . date . hour )
return 1 ;
else if ( x - > value . date . min < y - > value . date . min )
return - 1 ;
else if ( x - > value . date . min > y - > value . date . min )
return 1 ;
else if ( x - > value . date . sec < y - > value . date . sec )
return - 1 ;
else if ( x - > value . date . sec > y - > value . date . sec )
return 1 ;
}
2002-05-03 11:29:38 +04:00
return 0 ;
}
2005-02-17 14:10:44 +03:00
/**
* xmlSchemaComparePreserveReplaceStrings :
2005-03-16 19:29:18 +03:00
* @ x : a first string value
* @ y : a second string value
2005-02-17 14:10:44 +03:00
* @ invert : inverts the result if x < y or x > y .
*
* Compare 2 string for their normalized values .
* @ x is a string with whitespace of " preserve " , @ y is
* a string with a whitespace of " replace " . I . e . @ x could
* be an " xsd:string " and @ y an " xsd:normalizedString " .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
2005-03-16 19:29:18 +03:00
xmlSchemaComparePreserveReplaceStrings ( const xmlChar * x ,
const xmlChar * y ,
2005-02-17 14:10:44 +03:00
int invert )
{
int tmp ;
2012-09-11 09:26:36 +04:00
2005-03-16 19:29:18 +03:00
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if ( IS_WSP_REPLACE_CH ( * y ) ) {
if ( ! IS_WSP_SPACE_CH ( * x ) ) {
if ( ( * x - 0x20 ) < 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
} else {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
2012-09-11 09:26:36 +04:00
}
2005-02-17 14:10:44 +03:00
} else {
2005-03-16 19:29:18 +03:00
tmp = * x - * y ;
2005-02-17 14:10:44 +03:00
if ( tmp < 0 ) {
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
if ( tmp > 0 ) {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
2005-03-16 19:29:18 +03:00
x + + ;
y + + ;
2005-02-17 14:10:44 +03:00
}
2005-03-16 19:29:18 +03:00
if ( * x ! = 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
2005-03-16 19:29:18 +03:00
if ( * y ! = 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
return ( 0 ) ;
}
/**
* xmlSchemaComparePreserveCollapseStrings :
* @ x : a first string value
* @ y : a second string value
*
* Compare 2 string for their normalized values .
* @ x is a string with whitespace of " preserve " , @ y is
* a string with a whitespace of " collapse " . I . e . @ x could
* be an " xsd:string " and @ y an " xsd:normalizedString " .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
2005-03-16 19:29:18 +03:00
xmlSchemaComparePreserveCollapseStrings ( const xmlChar * x ,
const xmlChar * y ,
2005-02-17 14:10:44 +03:00
int invert )
{
int tmp ;
2012-09-11 09:26:36 +04:00
/*
2005-02-17 14:10:44 +03:00
* Skip leading blank chars of the collapsed string .
*/
2005-03-16 19:29:18 +03:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
2005-02-17 14:10:44 +03:00
2005-03-16 19:29:18 +03:00
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if IS_WSP_BLANK_CH ( * y ) {
if ( ! IS_WSP_SPACE_CH ( * x ) ) {
2005-02-17 14:10:44 +03:00
/*
2005-03-16 19:29:18 +03:00
* The yv character would have been replaced to 0x20 .
2005-02-17 14:10:44 +03:00
*/
2005-03-16 19:29:18 +03:00
if ( ( * x - 0x20 ) < 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
} else {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
2005-03-16 19:29:18 +03:00
x + + ;
y + + ;
2005-02-17 14:10:44 +03:00
/*
* Skip contiguous blank chars of the collapsed string .
*/
2005-03-16 19:29:18 +03:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
2005-02-17 14:10:44 +03:00
} else {
2005-03-16 19:29:18 +03:00
tmp = * x + + - * y + + ;
2005-02-17 14:10:44 +03:00
if ( tmp < 0 ) {
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
if ( tmp > 0 ) {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
}
2005-03-16 19:29:18 +03:00
if ( * x ! = 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
2005-03-16 19:29:18 +03:00
if ( * y ! = 0 ) {
2005-02-17 14:10:44 +03:00
/*
* Skip trailing blank chars of the collapsed string .
*/
2005-03-16 19:29:18 +03:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
if ( * y ! = 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
}
return ( 0 ) ;
}
/**
* xmlSchemaComparePreserveCollapseStrings :
* @ x : a first string value
* @ y : a second string value
*
* Compare 2 string for their normalized values .
* @ x is a string with whitespace of " preserve " , @ y is
* a string with a whitespace of " collapse " . I . e . @ x could
* be an " xsd:string " and @ y an " xsd:normalizedString " .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
2005-03-16 19:29:18 +03:00
xmlSchemaCompareReplaceCollapseStrings ( const xmlChar * x ,
const xmlChar * y ,
2005-02-17 14:10:44 +03:00
int invert )
{
int tmp ;
2012-09-11 09:26:36 +04:00
/*
2005-02-17 14:10:44 +03:00
* Skip leading blank chars of the collapsed string .
*/
2005-03-16 19:29:18 +03:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
2012-09-11 09:26:36 +04:00
2005-03-16 19:29:18 +03:00
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if IS_WSP_BLANK_CH ( * y ) {
if ( ! IS_WSP_BLANK_CH ( * x ) ) {
2005-02-17 14:10:44 +03:00
/*
2005-03-16 19:29:18 +03:00
* The yv character would have been replaced to 0x20 .
2005-02-17 14:10:44 +03:00
*/
2005-03-16 19:29:18 +03:00
if ( ( * x - 0x20 ) < 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
} else {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
2005-03-16 19:29:18 +03:00
x + + ;
2012-09-11 09:26:36 +04:00
y + + ;
/*
2005-02-17 14:10:44 +03:00
* Skip contiguous blank chars of the collapsed string .
*/
2005-03-16 19:29:18 +03:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
2005-02-17 14:10:44 +03:00
} else {
2005-03-16 19:29:18 +03:00
if IS_WSP_BLANK_CH ( * x ) {
2005-02-17 14:10:44 +03:00
/*
2005-03-16 19:29:18 +03:00
* The xv character would have been replaced to 0x20 .
2005-02-17 14:10:44 +03:00
*/
2005-03-16 19:29:18 +03:00
if ( ( 0x20 - * y ) < 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
} else {
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
}
}
2005-03-16 19:29:18 +03:00
tmp = * x + + - * y + + ;
2005-02-17 14:10:44 +03:00
if ( tmp < 0 )
return ( - 1 ) ;
if ( tmp > 0 )
return ( 1 ) ;
}
}
2005-03-16 19:29:18 +03:00
if ( * x ! = 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( - 1 ) ;
else
return ( 1 ) ;
2012-09-11 09:26:36 +04:00
}
2005-03-16 19:29:18 +03:00
if ( * y ! = 0 ) {
2005-02-17 14:10:44 +03:00
/*
* Skip trailing blank chars of the collapsed string .
*/
2005-03-16 19:29:18 +03:00
while IS_WSP_BLANK_CH ( * y )
y + + ;
if ( * y ! = 0 ) {
2005-02-17 14:10:44 +03:00
if ( invert )
return ( 1 ) ;
else
return ( - 1 ) ;
}
}
return ( 0 ) ;
}
/**
* xmlSchemaCompareReplacedStrings :
* @ x : a first string value
* @ y : a second string value
*
* Compare 2 string for their normalized values .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
2005-03-16 19:29:18 +03:00
xmlSchemaCompareReplacedStrings ( const xmlChar * x ,
const xmlChar * y )
2005-02-17 14:10:44 +03:00
{
int tmp ;
2012-09-11 09:26:36 +04:00
2005-03-16 19:29:18 +03:00
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if IS_WSP_BLANK_CH ( * y ) {
if ( ! IS_WSP_BLANK_CH ( * x ) ) {
if ( ( * x - 0x20 ) < 0 )
2012-09-11 09:26:36 +04:00
return ( - 1 ) ;
2005-02-17 14:10:44 +03:00
else
return ( 1 ) ;
2012-09-11 09:26:36 +04:00
}
2005-02-17 14:10:44 +03:00
} else {
2005-03-16 19:29:18 +03:00
if IS_WSP_BLANK_CH ( * x ) {
if ( ( 0x20 - * y ) < 0 )
2012-09-11 09:26:36 +04:00
return ( - 1 ) ;
2005-02-17 14:10:44 +03:00
else
return ( 1 ) ;
}
2005-03-16 19:29:18 +03:00
tmp = * x - * y ;
2005-02-17 14:10:44 +03:00
if ( tmp < 0 )
2012-09-11 09:26:36 +04:00
return ( - 1 ) ;
2005-02-17 14:10:44 +03:00
if ( tmp > 0 )
2012-09-11 09:26:36 +04:00
return ( 1 ) ;
2005-02-17 14:10:44 +03:00
}
2005-03-16 19:29:18 +03:00
x + + ;
y + + ;
2005-02-17 14:10:44 +03:00
}
2005-03-16 19:29:18 +03:00
if ( * x ! = 0 )
2005-02-17 14:10:44 +03:00
return ( 1 ) ;
2005-03-16 19:29:18 +03:00
if ( * y ! = 0 )
2005-02-17 14:10:44 +03:00
return ( - 1 ) ;
return ( 0 ) ;
}
2003-03-29 13:53:38 +03:00
/**
* xmlSchemaCompareNormStrings :
* @ x : a first string value
* @ y : a second string value
*
* Compare 2 string for their normalized values .
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , and - 2 in
* case of error
*/
static int
2005-03-16 19:29:18 +03:00
xmlSchemaCompareNormStrings ( const xmlChar * x ,
const xmlChar * y ) {
2003-03-29 13:53:38 +03:00
int tmp ;
2012-09-11 09:26:36 +04:00
2005-03-16 19:29:18 +03:00
while ( IS_BLANK_CH ( * x ) ) x + + ;
while ( IS_BLANK_CH ( * y ) ) y + + ;
while ( ( * x ! = 0 ) & & ( * y ! = 0 ) ) {
if ( IS_BLANK_CH ( * x ) ) {
if ( ! IS_BLANK_CH ( * y ) ) {
tmp = * x - * y ;
2003-03-29 13:53:38 +03:00
return ( tmp ) ;
}
2005-03-16 19:29:18 +03:00
while ( IS_BLANK_CH ( * x ) ) x + + ;
while ( IS_BLANK_CH ( * y ) ) y + + ;
2003-03-29 13:53:38 +03:00
} else {
2005-03-16 19:29:18 +03:00
tmp = * x + + - * y + + ;
2003-03-29 13:53:38 +03:00
if ( tmp < 0 )
return ( - 1 ) ;
if ( tmp > 0 )
return ( 1 ) ;
}
}
2005-03-16 19:29:18 +03:00
if ( * x ! = 0 ) {
while ( IS_BLANK_CH ( * x ) ) x + + ;
if ( * x ! = 0 )
2003-03-29 13:53:38 +03:00
return ( 1 ) ;
}
2005-03-16 19:29:18 +03:00
if ( * y ! = 0 ) {
while ( IS_BLANK_CH ( * y ) ) y + + ;
if ( * y ! = 0 )
2003-03-29 13:53:38 +03:00
return ( - 1 ) ;
}
return ( 0 ) ;
}
2003-03-29 19:41:55 +03:00
/**
* xmlSchemaCompareFloats :
* @ x : a first float or double value
* @ y : a second float or double value
*
* Compare 2 values
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
static int
xmlSchemaCompareFloats ( xmlSchemaValPtr x , xmlSchemaValPtr y ) {
double d1 , d2 ;
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
/*
* Cast everything to doubles .
*/
if ( x - > type = = XML_SCHEMAS_DOUBLE )
d1 = x - > value . d ;
else if ( x - > type = = XML_SCHEMAS_FLOAT )
d1 = x - > value . f ;
else
return ( - 2 ) ;
if ( y - > type = = XML_SCHEMAS_DOUBLE )
d2 = y - > value . d ;
else if ( y - > type = = XML_SCHEMAS_FLOAT )
d2 = y - > value . f ;
else
return ( - 2 ) ;
/*
* Check for special cases .
*/
2024-06-16 00:53:04 +03:00
if ( isnan ( d1 ) ) {
if ( isnan ( d2 ) )
2003-03-29 19:41:55 +03:00
return ( 0 ) ;
return ( 1 ) ;
}
2024-06-16 00:53:04 +03:00
if ( isnan ( d2 ) )
2003-03-29 19:41:55 +03:00
return ( - 1 ) ;
/*
* basic tests , the last one we should have equality , but
* portability is more important than speed and handling
* NaN or Inf in a portable way is always a challenge , so . . .
*/
if ( d1 < d2 )
return ( - 1 ) ;
if ( d1 > d2 )
return ( 1 ) ;
if ( d1 = = d2 )
return ( 0 ) ;
return ( 2 ) ;
}
2002-04-16 19:50:10 +04:00
/**
* xmlSchemaCompareValues :
* @ x : a first value
2005-03-15 17:58:11 +03:00
* @ xvalue : the first value as a string ( optional )
2005-02-17 14:10:44 +03:00
* @ xwtsp : the whitespace type
2002-04-16 19:50:10 +04:00
* @ y : a second value
2005-03-15 17:58:11 +03:00
* @ xvalue : the second value as a string ( optional )
2005-02-17 14:10:44 +03:00
* @ ywtsp : the whitespace type
2002-04-16 19:50:10 +04:00
*
* Compare 2 values
*
2005-06-09 14:32:53 +04:00
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , 3 if not
* comparable and - 2 in case of error
2002-04-16 19:50:10 +04:00
*/
2005-02-17 14:10:44 +03:00
static int
2005-03-15 17:58:11 +03:00
xmlSchemaCompareValuesInternal ( xmlSchemaValType xtype ,
xmlSchemaValPtr x ,
const xmlChar * xvalue ,
2005-02-17 14:10:44 +03:00
xmlSchemaWhitespaceValueType xws ,
2005-03-15 17:58:11 +03:00
xmlSchemaValType ytype ,
2005-02-17 14:10:44 +03:00
xmlSchemaValPtr y ,
2005-03-15 17:58:11 +03:00
const xmlChar * yvalue ,
2005-03-16 19:29:18 +03:00
xmlSchemaWhitespaceValueType yws )
{
2005-03-15 17:58:11 +03:00
switch ( xtype ) {
2003-03-28 16:29:53 +03:00
case XML_SCHEMAS_UNKNOWN :
modified parsing of <list>, <union>, <restriction>, <sequence>, <choice>,
* xmlschemas.c: modified parsing of <list>, <union>, <restriction>,
<sequence>, <choice>, <include>, <import>.
Fixed schema defaults (elementFormDefault, etc.) for included
schemas.
Fixed a bug which reported attributes as invalid on
elements declarations with the built-in type 'anyType'.
Added "lax" validation of the content of elements of type
'anyType'.
Fixed: element declarations with the same name were treated
as duplicate if located in the subtree of <choice> -> <sequence>.
(This was bug 150623, submitted by Roland Lezuo)
Fixed cleanup of error codes in xmlSchemaValidateDoc as proposed
by Igor Kapitanker. (This was bug 150647, submitted by Igor
Kapitanker)
* xmlschemastypes.c: Changed the type of anyType to
XML_SCHEMAS_ANYTYPE.
* include/libxml/xmlerror.h: Added schema parser errors.
* result/schemas/bug145246_0_0*
result/schemas/extension1_0_2.err: Changed test results.
* result/schemas/ct-sc-nobase_0_0*
result/schemas/facet-whiteSpace_0_0*
result/schemas/import1_0_0* result/schemas/import2_0_0*
result/schemas/include2_0_0* result/schemas/include3_0_0*
result/schemas/restriction-attr1_0_0*
result/schemas/seq-dubl-elem1_0_0*
result/schemas/xsd-list-itemType_0_0*: Added new rest results.
test/schemas/bug145246.xsd.imp test/schemas/ct-sc-nobase_0*
test/schemas/facet-whiteSpace_0* test/schemas/import1_0*
test/schemas/import2_0* test/schemas/include2_0*
test/schemas/include3_0* test/schemas/restriction-attr1_0*
test/schemas/seq-dubl-elem1_0* test/schemas/xml.xsd
test/schemas/xsd-list-itemType_0*: Added new tests and missing
files.
2004-08-21 03:09:47 +04:00
case XML_SCHEMAS_ANYTYPE :
2003-03-28 16:29:53 +03:00
return ( - 2 ) ;
case XML_SCHEMAS_INTEGER :
case XML_SCHEMAS_NPINTEGER :
case XML_SCHEMAS_NINTEGER :
case XML_SCHEMAS_NNINTEGER :
case XML_SCHEMAS_PINTEGER :
case XML_SCHEMAS_INT :
case XML_SCHEMAS_UINT :
case XML_SCHEMAS_LONG :
case XML_SCHEMAS_ULONG :
case XML_SCHEMAS_SHORT :
case XML_SCHEMAS_USHORT :
case XML_SCHEMAS_BYTE :
case XML_SCHEMAS_UBYTE :
2002-04-16 19:50:10 +04:00
case XML_SCHEMAS_DECIMAL :
2005-03-15 17:58:11 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ytype = = xtype )
2003-03-28 16:29:53 +03:00
return ( xmlSchemaCompareDecimals ( x , y ) ) ;
2005-03-15 17:58:11 +03:00
if ( ( ytype = = XML_SCHEMAS_DECIMAL ) | |
( ytype = = XML_SCHEMAS_INTEGER ) | |
( ytype = = XML_SCHEMAS_NPINTEGER ) | |
( ytype = = XML_SCHEMAS_NINTEGER ) | |
( ytype = = XML_SCHEMAS_NNINTEGER ) | |
( ytype = = XML_SCHEMAS_PINTEGER ) | |
( ytype = = XML_SCHEMAS_INT ) | |
( ytype = = XML_SCHEMAS_UINT ) | |
( ytype = = XML_SCHEMAS_LONG ) | |
( ytype = = XML_SCHEMAS_ULONG ) | |
( ytype = = XML_SCHEMAS_SHORT ) | |
( ytype = = XML_SCHEMAS_USHORT ) | |
( ytype = = XML_SCHEMAS_BYTE ) | |
( ytype = = XML_SCHEMAS_UBYTE ) )
2002-04-16 19:50:10 +04:00
return ( xmlSchemaCompareDecimals ( x , y ) ) ;
2002-05-22 10:40:27 +04:00
return ( - 2 ) ;
2002-05-03 11:29:38 +04:00
case XML_SCHEMAS_DURATION :
2005-03-15 17:58:11 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
2005-03-16 19:29:18 +03:00
if ( ytype = = XML_SCHEMAS_DURATION )
2002-05-03 11:29:38 +04:00
return ( xmlSchemaCompareDurations ( x , y ) ) ;
2002-05-22 10:40:27 +04:00
return ( - 2 ) ;
case XML_SCHEMAS_TIME :
case XML_SCHEMAS_GDAY :
case XML_SCHEMAS_GMONTH :
case XML_SCHEMAS_GMONTHDAY :
case XML_SCHEMAS_GYEAR :
case XML_SCHEMAS_GYEARMONTH :
case XML_SCHEMAS_DATE :
case XML_SCHEMAS_DATETIME :
2005-03-15 17:58:11 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ( ytype = = XML_SCHEMAS_DATETIME ) | |
( ytype = = XML_SCHEMAS_TIME ) | |
( ytype = = XML_SCHEMAS_GDAY ) | |
( ytype = = XML_SCHEMAS_GMONTH ) | |
( ytype = = XML_SCHEMAS_GMONTHDAY ) | |
( ytype = = XML_SCHEMAS_GYEAR ) | |
( ytype = = XML_SCHEMAS_DATE ) | |
( ytype = = XML_SCHEMAS_GYEARMONTH ) )
2002-05-22 10:40:27 +04:00
return ( xmlSchemaCompareDates ( x , y ) ) ;
return ( - 2 ) ;
2012-09-11 09:26:36 +04:00
/*
2005-03-07 14:14:14 +03:00
* Note that we will support comparison of string types against
* anySimpleType as well .
*/
case XML_SCHEMAS_ANYSIMPLETYPE :
2005-02-17 14:10:44 +03:00
case XML_SCHEMAS_STRING :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_NORMSTRING :
2003-03-28 16:29:53 +03:00
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_ENTITY :
case XML_SCHEMAS_ANYURI :
2005-03-15 17:58:11 +03:00
{
const xmlChar * xv , * yv ;
if ( x = = NULL )
xv = xvalue ;
else
xv = x - > value . str ;
if ( y = = NULL )
yv = yvalue ;
else
yv = y - > value . str ;
2005-02-17 14:10:44 +03:00
/*
* TODO : Compare those against QName .
*/
2012-09-11 09:26:36 +04:00
if ( ytype = = XML_SCHEMAS_QNAME ) {
2023-12-18 21:51:32 +03:00
/* TODO */
2005-03-15 17:58:11 +03:00
if ( y = = NULL )
2012-09-11 09:26:36 +04:00
return ( - 2 ) ;
2005-02-17 14:10:44 +03:00
return ( - 2 ) ;
}
2005-03-15 17:58:11 +03:00
if ( ( ytype = = XML_SCHEMAS_ANYSIMPLETYPE ) | |
( ytype = = XML_SCHEMAS_STRING ) | |
( ytype = = XML_SCHEMAS_NORMSTRING ) | |
( ytype = = XML_SCHEMAS_TOKEN ) | |
( ytype = = XML_SCHEMAS_LANGUAGE ) | |
( ytype = = XML_SCHEMAS_NMTOKEN ) | |
( ytype = = XML_SCHEMAS_NAME ) | |
( ytype = = XML_SCHEMAS_NCNAME ) | |
( ytype = = XML_SCHEMAS_ID ) | |
( ytype = = XML_SCHEMAS_IDREF ) | |
( ytype = = XML_SCHEMAS_ENTITY ) | |
( ytype = = XML_SCHEMAS_ANYURI ) ) {
2005-02-17 14:10:44 +03:00
if ( xws = = XML_SCHEMA_WHITESPACE_PRESERVE ) {
if ( yws = = XML_SCHEMA_WHITESPACE_PRESERVE ) {
/* TODO: What about x < y or x > y. */
2005-03-15 17:58:11 +03:00
if ( xmlStrEqual ( xv , yv ) )
2005-02-17 14:10:44 +03:00
return ( 0 ) ;
2012-09-11 09:26:36 +04:00
else
2005-02-17 14:10:44 +03:00
return ( 2 ) ;
} else if ( yws = = XML_SCHEMA_WHITESPACE_REPLACE )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaComparePreserveReplaceStrings ( xv , yv , 0 ) ) ;
2005-02-17 14:10:44 +03:00
else if ( yws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaComparePreserveCollapseStrings ( xv , yv , 0 ) ) ;
2005-02-17 14:10:44 +03:00
} else if ( xws = = XML_SCHEMA_WHITESPACE_REPLACE ) {
if ( yws = = XML_SCHEMA_WHITESPACE_PRESERVE )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaComparePreserveReplaceStrings ( yv , xv , 1 ) ) ;
2005-02-17 14:10:44 +03:00
if ( yws = = XML_SCHEMA_WHITESPACE_REPLACE )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaCompareReplacedStrings ( xv , yv ) ) ;
2005-02-17 14:10:44 +03:00
if ( yws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaCompareReplaceCollapseStrings ( xv , yv , 0 ) ) ;
2005-02-17 14:10:44 +03:00
} else if ( xws = = XML_SCHEMA_WHITESPACE_COLLAPSE ) {
if ( yws = = XML_SCHEMA_WHITESPACE_PRESERVE )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaComparePreserveCollapseStrings ( yv , xv , 1 ) ) ;
2005-02-17 14:10:44 +03:00
if ( yws = = XML_SCHEMA_WHITESPACE_REPLACE )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaCompareReplaceCollapseStrings ( yv , xv , 1 ) ) ;
2005-02-17 14:10:44 +03:00
if ( yws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaCompareNormStrings ( xv , yv ) ) ;
2005-02-17 14:10:44 +03:00
} else
return ( - 2 ) ;
2012-09-11 09:26:36 +04:00
2005-02-17 14:10:44 +03:00
}
2003-03-29 13:53:38 +03:00
return ( - 2 ) ;
2005-03-15 17:58:11 +03:00
}
2003-03-31 01:10:09 +04:00
case XML_SCHEMAS_QNAME :
2005-04-18 14:57:04 +04:00
case XML_SCHEMAS_NOTATION :
2005-03-15 17:58:11 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
2005-04-18 14:57:04 +04:00
if ( ( ytype = = XML_SCHEMAS_QNAME ) | |
( ytype = = XML_SCHEMAS_NOTATION ) ) {
2003-03-31 01:10:09 +04:00
if ( ( xmlStrEqual ( x - > value . qname . name , y - > value . qname . name ) ) & &
( xmlStrEqual ( x - > value . qname . uri , y - > value . qname . uri ) ) )
return ( 0 ) ;
return ( 2 ) ;
}
return ( - 2 ) ;
2003-03-29 13:53:38 +03:00
case XML_SCHEMAS_FLOAT :
case XML_SCHEMAS_DOUBLE :
2005-03-15 17:58:11 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ( ytype = = XML_SCHEMAS_FLOAT ) | |
( ytype = = XML_SCHEMAS_DOUBLE ) )
2003-03-29 19:41:55 +03:00
return ( xmlSchemaCompareFloats ( x , y ) ) ;
return ( - 2 ) ;
2003-03-29 13:53:38 +03:00
case XML_SCHEMAS_BOOLEAN :
2005-03-15 17:58:11 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ytype = = XML_SCHEMAS_BOOLEAN ) {
2003-03-29 19:41:55 +03:00
if ( x - > value . b = = y - > value . b )
return ( 0 ) ;
if ( x - > value . b = = 0 )
return ( - 1 ) ;
return ( 1 ) ;
}
return ( - 2 ) ;
2003-07-07 01:13:49 +04:00
case XML_SCHEMAS_HEXBINARY :
2005-03-15 17:58:11 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ytype = = XML_SCHEMAS_HEXBINARY ) {
2003-08-08 18:00:28 +04:00
if ( x - > value . hex . total = = y - > value . hex . total ) {
int ret = xmlStrcmp ( x - > value . hex . str , y - > value . hex . str ) ;
if ( ret > 0 )
return ( 1 ) ;
else if ( ret = = 0 )
return ( 0 ) ;
}
else if ( x - > value . hex . total > y - > value . hex . total )
return ( 1 ) ;
return ( - 1 ) ;
}
2003-07-07 01:13:49 +04:00
return ( - 2 ) ;
2003-08-27 18:15:15 +04:00
case XML_SCHEMAS_BASE64BINARY :
2005-03-15 17:58:11 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
if ( ytype = = XML_SCHEMAS_BASE64BINARY ) {
2003-08-27 18:15:15 +04:00
if ( x - > value . base64 . total = = y - > value . base64 . total ) {
int ret = xmlStrcmp ( x - > value . base64 . str ,
y - > value . base64 . str ) ;
if ( ret > 0 )
return ( 1 ) ;
else if ( ret = = 0 )
return ( 0 ) ;
2005-07-14 19:54:44 +04:00
else
return ( - 1 ) ;
2003-08-27 18:15:15 +04:00
}
else if ( x - > value . base64 . total > y - > value . base64 . total )
return ( 1 ) ;
else
return ( - 1 ) ;
}
2012-09-11 09:26:36 +04:00
return ( - 2 ) ;
2003-03-29 13:53:38 +03:00
case XML_SCHEMAS_IDREFS :
case XML_SCHEMAS_ENTITIES :
case XML_SCHEMAS_NMTOKENS :
2023-12-18 21:51:32 +03:00
/* TODO */
2003-03-29 13:53:38 +03:00
break ;
2002-04-16 19:50:10 +04:00
}
2002-05-22 10:40:27 +04:00
return - 2 ;
2002-04-16 19:50:10 +04:00
}
2005-02-17 14:10:44 +03:00
/**
* xmlSchemaCompareValues :
* @ x : a first value
* @ y : a second value
*
* Compare 2 values
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
int
xmlSchemaCompareValues ( xmlSchemaValPtr x , xmlSchemaValPtr y ) {
xmlSchemaWhitespaceValueType xws , yws ;
2005-02-18 22:36:12 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
2005-02-17 14:10:44 +03:00
if ( x - > type = = XML_SCHEMAS_STRING )
xws = XML_SCHEMA_WHITESPACE_PRESERVE ;
else if ( x - > type = = XML_SCHEMAS_NORMSTRING )
xws = XML_SCHEMA_WHITESPACE_REPLACE ;
else
xws = XML_SCHEMA_WHITESPACE_COLLAPSE ;
if ( y - > type = = XML_SCHEMAS_STRING )
yws = XML_SCHEMA_WHITESPACE_PRESERVE ;
2013-11-28 18:50:57 +04:00
else if ( y - > type = = XML_SCHEMAS_NORMSTRING )
2005-02-17 14:10:44 +03:00
yws = XML_SCHEMA_WHITESPACE_REPLACE ;
else
yws = XML_SCHEMA_WHITESPACE_COLLAPSE ;
2005-03-15 17:58:11 +03:00
return ( xmlSchemaCompareValuesInternal ( x - > type , x , NULL , xws , y - > type ,
y , NULL , yws ) ) ;
2005-02-17 14:10:44 +03:00
}
/**
* xmlSchemaCompareValuesWhtsp :
* @ x : a first value
* @ xws : the whitespace value of x
* @ y : a second value
* @ yws : the whitespace value of y
*
* Compare 2 values
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
int
xmlSchemaCompareValuesWhtsp ( xmlSchemaValPtr x ,
2005-03-15 17:58:11 +03:00
xmlSchemaWhitespaceValueType xws ,
xmlSchemaValPtr y ,
xmlSchemaWhitespaceValueType yws )
{
2005-03-16 19:39:23 +03:00
if ( ( x = = NULL ) | | ( y = = NULL ) )
return ( - 2 ) ;
2005-03-15 17:58:11 +03:00
return ( xmlSchemaCompareValuesInternal ( x - > type , x , NULL , xws , y - > type ,
y , NULL , yws ) ) ;
}
/**
* xmlSchemaCompareValuesWhtspExt :
* @ x : a first value
* @ xws : the whitespace value of x
* @ y : a second value
* @ yws : the whitespace value of y
*
* Compare 2 values
*
* Returns - 1 if x < y , 0 if x = = y , 1 if x > y , 2 if x < > y , and - 2 in
* case of error
*/
static int
xmlSchemaCompareValuesWhtspExt ( xmlSchemaValType xtype ,
xmlSchemaValPtr x ,
const xmlChar * xvalue ,
xmlSchemaWhitespaceValueType xws ,
xmlSchemaValType ytype ,
xmlSchemaValPtr y ,
const xmlChar * yvalue ,
xmlSchemaWhitespaceValueType yws )
{
return ( xmlSchemaCompareValuesInternal ( xtype , x , xvalue , xws , ytype , y ,
yvalue , yws ) ) ;
2005-02-17 14:10:44 +03:00
}
2003-03-29 13:53:38 +03:00
/**
* xmlSchemaNormLen :
* @ value : a string
*
* Computes the UTF8 length of the normalized value of the string
*
* Returns the length or - 1 in case of error .
*/
static int
xmlSchemaNormLen ( const xmlChar * value ) {
const xmlChar * utf ;
int ret = 0 ;
if ( value = = NULL )
return ( - 1 ) ;
utf = value ;
2003-10-18 20:20:14 +04:00
while ( IS_BLANK_CH ( * utf ) ) utf + + ;
2003-03-29 13:53:38 +03:00
while ( * utf ! = 0 ) {
if ( utf [ 0 ] & 0x80 ) {
if ( ( utf [ 1 ] & 0xc0 ) ! = 0x80 )
return ( - 1 ) ;
if ( ( utf [ 0 ] & 0xe0 ) = = 0xe0 ) {
if ( ( utf [ 2 ] & 0xc0 ) ! = 0x80 )
return ( - 1 ) ;
if ( ( utf [ 0 ] & 0xf0 ) = = 0xf0 ) {
if ( ( utf [ 0 ] & 0xf8 ) ! = 0xf0 | | ( utf [ 3 ] & 0xc0 ) ! = 0x80 )
return ( - 1 ) ;
utf + = 4 ;
} else {
utf + = 3 ;
}
} else {
utf + = 2 ;
}
2003-10-18 20:20:14 +04:00
} else if ( IS_BLANK_CH ( * utf ) ) {
while ( IS_BLANK_CH ( * utf ) ) utf + + ;
2003-03-29 13:53:38 +03:00
if ( * utf = = 0 )
break ;
} else {
utf + + ;
}
ret + + ;
}
return ( ret ) ;
}
2004-10-27 21:29:04 +04:00
/**
* xmlSchemaGetFacetValueAsULong :
* @ facet : an schemas type facet
*
* Extract the value of a facet
*
* Returns the value as a long
*/
2004-08-10 18:17:33 +04:00
unsigned long
xmlSchemaGetFacetValueAsULong ( xmlSchemaFacetPtr facet )
{
/*
* TODO : Check if this is a decimal .
*/
2023-11-07 23:08:01 +03:00
char * discard ;
2020-12-07 15:17:34 +03:00
if ( facet = = NULL | | facet - > val = = NULL )
2004-11-14 17:28:34 +03:00
return 0 ;
2023-11-07 23:08:01 +03:00
return strtoul ( ( const char * ) facet - > val - > value . decimal . str + 1 , & discard , 10 ) ;
2004-08-10 18:17:33 +04:00
}
2004-06-29 21:04:39 +04:00
/**
* xmlSchemaValidateListSimpleTypeFacet :
* @ facet : the facet to check
* @ value : the lexical repr of the value to validate
* @ actualLen : the number of list items
* @ expectedLen : the resulting expected number of list items
*
* Checks the value of a list simple type against a facet .
*
* Returns 0 if the value is valid , a positive error code
* number otherwise and - 1 in case of an internal error .
*/
int
xmlSchemaValidateListSimpleTypeFacet ( xmlSchemaFacetPtr facet ,
const xmlChar * value ,
unsigned long actualLen ,
unsigned long * expectedLen )
{
2004-11-05 20:22:25 +03:00
if ( facet = = NULL )
return ( - 1 ) ;
2004-06-29 21:04:39 +04:00
/*
* TODO : Check if this will work with large numbers .
* ( compare value . decimal . mi and value . decimal . hi as well ? ) .
*/
if ( facet - > type = = XML_SCHEMA_FACET_LENGTH ) {
2023-11-07 23:08:01 +03:00
if ( actualLen ! = xmlSchemaGetFacetValueAsULong ( facet ) ) {
2005-03-16 19:29:18 +03:00
if ( expectedLen ! = NULL )
2023-11-07 23:08:01 +03:00
* expectedLen = xmlSchemaGetFacetValueAsULong ( facet ) ;
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_LENGTH_VALID ) ;
2012-09-11 09:26:36 +04:00
}
2004-06-29 21:04:39 +04:00
} else if ( facet - > type = = XML_SCHEMA_FACET_MINLENGTH ) {
2023-11-07 23:08:01 +03:00
if ( actualLen < xmlSchemaGetFacetValueAsULong ( facet ) ) {
2005-03-16 19:29:18 +03:00
if ( expectedLen ! = NULL )
2023-11-07 23:08:01 +03:00
* expectedLen = xmlSchemaGetFacetValueAsULong ( facet ) ;
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_MINLENGTH_VALID ) ;
}
} else if ( facet - > type = = XML_SCHEMA_FACET_MAXLENGTH ) {
2023-11-07 23:08:01 +03:00
if ( actualLen > xmlSchemaGetFacetValueAsULong ( facet ) ) {
2005-03-16 19:29:18 +03:00
if ( expectedLen ! = NULL )
2023-11-07 23:08:01 +03:00
* expectedLen = xmlSchemaGetFacetValueAsULong ( facet ) ;
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_MAXLENGTH_VALID ) ;
}
} else
2012-09-11 09:26:36 +04:00
/*
* NOTE : That we can pass NULL as xmlSchemaValPtr to
2004-06-29 21:04:39 +04:00
* xmlSchemaValidateFacet , since the remaining facet types
2012-09-11 09:26:36 +04:00
* are : XML_SCHEMA_FACET_PATTERN , XML_SCHEMA_FACET_ENUMERATION .
2004-06-29 21:04:39 +04:00
*/
2012-09-11 09:26:36 +04:00
return ( xmlSchemaValidateFacet ( NULL , facet , value , NULL ) ) ;
2004-06-29 21:04:39 +04:00
return ( 0 ) ;
}
2004-08-10 18:17:33 +04:00
/**
2004-10-27 21:29:04 +04:00
* xmlSchemaValidateLengthFacet :
2004-08-10 18:17:33 +04:00
* @ type : the built - in type
* @ facet : the facet to check
* @ value : the lexical repr . of the value to be validated
* @ val : the precomputed value
2005-03-16 19:29:18 +03:00
* @ ws : the whitespace type of the value
2004-08-10 18:17:33 +04:00
* @ length : the actual length of the value
*
2012-09-11 09:26:36 +04:00
* Checka a value against a " length " , " minLength " and " maxLength "
2004-08-10 18:17:33 +04:00
* facet ; sets @ length to the computed length of @ value .
*
* Returns 0 if the value is valid , a positive error code
* otherwise and - 1 in case of an internal or API error .
*/
2005-03-16 19:29:18 +03:00
static int
xmlSchemaValidateLengthFacetInternal ( xmlSchemaFacetPtr facet ,
2012-02-29 05:44:35 +04:00
xmlSchemaValType valType ,
2005-03-16 19:29:18 +03:00
const xmlChar * value ,
2012-02-29 05:44:35 +04:00
xmlSchemaValPtr val ,
2005-03-16 19:29:18 +03:00
unsigned long * length ,
2012-09-11 09:26:36 +04:00
xmlSchemaWhitespaceValueType ws )
2004-08-10 18:17:33 +04:00
{
unsigned int len = 0 ;
2005-03-16 19:29:18 +03:00
if ( ( length = = NULL ) | | ( facet = = NULL ) )
2004-11-05 20:22:25 +03:00
return ( - 1 ) ;
2004-08-10 18:17:33 +04:00
* length = 0 ;
if ( ( facet - > type ! = XML_SCHEMA_FACET_LENGTH ) & &
( facet - > type ! = XML_SCHEMA_FACET_MAXLENGTH ) & &
( facet - > type ! = XML_SCHEMA_FACET_MINLENGTH ) )
return ( - 1 ) ;
2012-09-11 09:26:36 +04:00
2005-03-16 19:29:18 +03:00
/*
* TODO : length , maxLength and minLength must be of type
* nonNegativeInteger only . Check if decimal is used somehow .
*/
2004-08-10 18:17:33 +04:00
if ( ( facet - > val = = NULL ) | |
( ( facet - > val - > type ! = XML_SCHEMAS_DECIMAL ) & &
( facet - > val - > type ! = XML_SCHEMAS_NNINTEGER ) ) | |
2023-11-07 23:08:01 +03:00
! ( xmlSchemaValDecimalIsInteger ( & facet - > val - > value . decimal ) ) )
{
2004-08-10 18:17:33 +04:00
return ( - 1 ) ;
}
if ( ( val ! = NULL ) & & ( val - > type = = XML_SCHEMAS_HEXBINARY ) )
len = val - > value . hex . total ;
else if ( ( val ! = NULL ) & & ( val - > type = = XML_SCHEMAS_BASE64BINARY ) )
len = val - > value . base64 . total ;
else {
2005-03-16 19:29:18 +03:00
switch ( valType ) {
case XML_SCHEMAS_STRING :
2004-08-10 18:17:33 +04:00
case XML_SCHEMAS_NORMSTRING :
2005-03-16 19:29:18 +03:00
if ( ws = = XML_SCHEMA_WHITESPACE_UNKNOWN ) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateLengthFacet ( ) . Anyway , this was and
* is not the correct handling .
* TODO : Get rid of this case somehow .
*/
if ( valType = = XML_SCHEMAS_STRING )
len = xmlUTF8Strlen ( value ) ;
else
len = xmlSchemaNormLen ( value ) ;
} else if ( value ! = NULL ) {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
len = xmlSchemaNormLen ( value ) ;
else
2012-09-11 09:26:36 +04:00
/*
2005-03-16 19:29:18 +03:00
* Should be OK for " preserve " as well .
*/
len = xmlUTF8Strlen ( value ) ;
}
break ;
case XML_SCHEMAS_IDREF :
2004-08-10 18:17:33 +04:00
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_ID :
2005-05-25 21:29:36 +04:00
/*
* FIXME : What exactly to do with anyURI ?
2005-03-16 19:29:18 +03:00
*/
2004-08-10 18:17:33 +04:00
case XML_SCHEMAS_ANYURI :
if ( value ! = NULL )
2005-03-16 19:29:18 +03:00
len = xmlSchemaNormLen ( value ) ;
2004-08-10 18:17:33 +04:00
break ;
2005-05-25 21:29:36 +04:00
case XML_SCHEMAS_QNAME :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_NOTATION :
/*
2005-06-09 14:32:53 +04:00
* For QName and NOTATION , those facets are
* deprecated and should be ignored .
2012-09-11 09:26:36 +04:00
*/
2005-05-25 21:29:36 +04:00
return ( 0 ) ;
2004-08-10 18:17:33 +04:00
default :
2023-12-18 21:51:32 +03:00
/* TODO */
break ;
2004-08-10 18:17:33 +04:00
}
}
* length = ( unsigned long ) len ;
2005-03-16 19:29:18 +03:00
/*
2023-11-07 23:08:01 +03:00
* TODO : Return the whole expected value . ( This may be possible now with xmlSchemaValDecimalCompareWithInteger )
2005-03-16 19:29:18 +03:00
*/
2004-08-10 18:17:33 +04:00
if ( facet - > type = = XML_SCHEMA_FACET_LENGTH ) {
2023-11-07 23:08:01 +03:00
if ( len ! = xmlSchemaGetFacetValueAsULong ( facet ) )
2004-08-10 18:17:33 +04:00
return ( XML_SCHEMAV_CVC_LENGTH_VALID ) ;
} else if ( facet - > type = = XML_SCHEMA_FACET_MINLENGTH ) {
2023-11-07 23:08:01 +03:00
if ( len < xmlSchemaGetFacetValueAsULong ( facet ) )
2004-08-10 18:17:33 +04:00
return ( XML_SCHEMAV_CVC_MINLENGTH_VALID ) ;
} else {
2023-11-07 23:08:01 +03:00
if ( len > xmlSchemaGetFacetValueAsULong ( facet ) )
2004-08-10 18:17:33 +04:00
return ( XML_SCHEMAV_CVC_MAXLENGTH_VALID ) ;
}
2012-09-11 09:26:36 +04:00
2004-08-10 18:17:33 +04:00
return ( 0 ) ;
}
2005-03-16 19:29:18 +03:00
/**
* xmlSchemaValidateLengthFacet :
* @ type : the built - in type
* @ facet : the facet to check
* @ value : the lexical repr . of the value to be validated
* @ val : the precomputed value
* @ length : the actual length of the value
*
2012-09-11 09:26:36 +04:00
* Checka a value against a " length " , " minLength " and " maxLength "
2005-03-16 19:29:18 +03:00
* facet ; sets @ length to the computed length of @ value .
*
* Returns 0 if the value is valid , a positive error code
* otherwise and - 1 in case of an internal or API error .
*/
int
2012-09-11 09:26:36 +04:00
xmlSchemaValidateLengthFacet ( xmlSchemaTypePtr type ,
2005-03-16 19:29:18 +03:00
xmlSchemaFacetPtr facet ,
const xmlChar * value ,
xmlSchemaValPtr val ,
2012-09-11 09:26:36 +04:00
unsigned long * length )
2005-03-16 19:29:18 +03:00
{
2005-03-17 00:55:35 +03:00
if ( type = = NULL )
return ( - 1 ) ;
2005-03-16 19:29:18 +03:00
return ( xmlSchemaValidateLengthFacetInternal ( facet ,
type - > builtInType , value , val , length ,
XML_SCHEMA_WHITESPACE_UNKNOWN ) ) ;
}
/**
2012-09-11 09:26:36 +04:00
* xmlSchemaValidateLengthFacetWhtsp :
2005-03-16 19:29:18 +03:00
* @ facet : the facet to check
* @ valType : the built - in type
* @ value : the lexical repr . of the value to be validated
* @ val : the precomputed value
* @ ws : the whitespace type of the value
* @ length : the actual length of the value
*
2012-09-11 09:26:36 +04:00
* Checka a value against a " length " , " minLength " and " maxLength "
2005-03-16 19:29:18 +03:00
* facet ; sets @ length to the computed length of @ value .
*
* Returns 0 if the value is valid , a positive error code
* otherwise and - 1 in case of an internal or API error .
*/
int
xmlSchemaValidateLengthFacetWhtsp ( xmlSchemaFacetPtr facet ,
xmlSchemaValType valType ,
const xmlChar * value ,
xmlSchemaValPtr val ,
unsigned long * length ,
xmlSchemaWhitespaceValueType ws )
{
return ( xmlSchemaValidateLengthFacetInternal ( facet , valType , value , val ,
length , ws ) ) ;
}
2002-04-16 19:50:10 +04:00
/**
2005-03-15 17:58:11 +03:00
* xmlSchemaValidateFacetInternal :
2002-04-16 19:50:10 +04:00
* @ facet : the facet to check
2005-03-16 19:29:18 +03:00
* @ fws : the whitespace type of the facet ' s value
* @ valType : the built - in type of the value
2002-04-16 19:50:10 +04:00
* @ value : the lexical repr of the value to validate
* @ val : the precomputed value
2005-03-16 19:29:18 +03:00
* @ ws : the whitespace type of the value
2002-04-16 19:50:10 +04:00
*
* Check a value against a facet condition
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
2005-03-15 17:58:11 +03:00
static int
xmlSchemaValidateFacetInternal ( xmlSchemaFacetPtr facet ,
xmlSchemaWhitespaceValueType fws ,
2012-09-11 09:26:36 +04:00
xmlSchemaValType valType ,
2005-03-15 17:58:11 +03:00
const xmlChar * value ,
2005-03-16 19:29:18 +03:00
xmlSchemaValPtr val ,
2005-03-15 17:58:11 +03:00
xmlSchemaWhitespaceValueType ws )
2002-04-16 19:50:10 +04:00
{
int ret ;
2005-03-15 17:58:11 +03:00
if ( facet = = NULL )
return ( - 1 ) ;
2002-04-16 19:50:10 +04:00
switch ( facet - > type ) {
case XML_SCHEMA_FACET_PATTERN :
2012-09-11 09:26:36 +04:00
/*
2005-03-15 17:58:11 +03:00
* NOTE that for patterns , the @ value needs to be the normalized
* value , * not * the lexical initial value or the canonical value .
*/
if ( value = = NULL )
return ( - 1 ) ;
2016-04-15 17:41:24 +03:00
/*
* If string - derived type , regexp must be tested on the value space of
* the datatype .
* See https : //www.w3.org/TR/xmlschema-2/#rf-pattern
*/
2022-02-08 06:30:29 +03:00
if ( val & &
val - > value . str & &
( ( val - > type > = XML_SCHEMAS_STRING & &
val - > type < = XML_SCHEMAS_NORMSTRING ) | |
( val - > type > = XML_SCHEMAS_TOKEN & &
val - > type < = XML_SCHEMAS_ENTITIES & &
val - > type ! = XML_SCHEMAS_QNAME ) ) ) {
value = val - > value . str ;
}
ret = xmlRegexpExec ( facet - > regexp , value ) ;
2002-04-16 19:50:10 +04:00
if ( ret = = 1 )
return ( 0 ) ;
2005-03-15 17:58:11 +03:00
if ( ret = = 0 )
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_PATTERN_VALID ) ;
2002-04-16 19:50:10 +04:00
return ( ret ) ;
case XML_SCHEMA_FACET_MAXEXCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
2005-03-15 17:58:11 +03:00
if ( ret = = - 2 )
2002-04-16 19:50:10 +04:00
return ( - 1 ) ;
if ( ret = = - 1 )
return ( 0 ) ;
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID ) ;
2002-05-03 11:29:38 +04:00
case XML_SCHEMA_FACET_MAXINCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
2005-03-15 17:58:11 +03:00
if ( ret = = - 2 )
2002-05-03 11:29:38 +04:00
return ( - 1 ) ;
if ( ( ret = = - 1 ) | | ( ret = = 0 ) )
return ( 0 ) ;
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID ) ;
2002-05-03 11:29:38 +04:00
case XML_SCHEMA_FACET_MINEXCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
2005-03-15 17:58:11 +03:00
if ( ret = = - 2 )
2002-05-03 11:29:38 +04:00
return ( - 1 ) ;
if ( ret = = 1 )
return ( 0 ) ;
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID ) ;
2002-05-03 11:29:38 +04:00
case XML_SCHEMA_FACET_MININCLUSIVE :
ret = xmlSchemaCompareValues ( val , facet - > val ) ;
2005-03-15 17:58:11 +03:00
if ( ret = = - 2 )
2002-05-03 11:29:38 +04:00
return ( - 1 ) ;
if ( ( ret = = 1 ) | | ( ret = = 0 ) )
return ( 0 ) ;
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_MININCLUSIVE_VALID ) ;
2002-04-17 13:06:27 +04:00
case XML_SCHEMA_FACET_WHITESPACE :
2003-02-27 20:42:22 +03:00
/* TODO whitespaces */
2004-06-29 21:04:39 +04:00
/*
* NOTE : Whitespace should be handled to normalize
* the value to be validated against a the facets ;
* not to normalize the value in - between .
*/
2002-04-17 13:06:27 +04:00
return ( 0 ) ;
2003-02-27 20:42:22 +03:00
case XML_SCHEMA_FACET_ENUMERATION :
2005-03-16 19:29:18 +03:00
if ( ws = = XML_SCHEMA_WHITESPACE_UNKNOWN ) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateFacet ( ) .
* TODO : Get rid of this case .
*/
2005-03-15 17:58:11 +03:00
if ( ( facet - > value ! = NULL ) & &
( xmlStrEqual ( facet - > value , value ) ) )
return ( 0 ) ;
} else {
ret = xmlSchemaCompareValuesWhtspExt ( facet - > val - > type ,
facet - > val , facet - > value , fws , valType , val ,
value , ws ) ;
if ( ret = = - 2 )
return ( - 1 ) ;
if ( ret = = 0 )
return ( 0 ) ;
}
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_ENUMERATION_VALID ) ;
2003-02-27 20:42:22 +03:00
case XML_SCHEMA_FACET_LENGTH :
2005-04-01 19:17:27 +04:00
/*
* SPEC ( 1.3 ) " if { primitive type definition } is QName or NOTATION ,
* then any { value } is facet - valid . "
*/
if ( ( valType = = XML_SCHEMAS_QNAME ) | |
( valType = = XML_SCHEMAS_NOTATION ) )
return ( 0 ) ;
2017-10-21 14:49:31 +03:00
/* Falls through. */
2002-04-22 20:01:24 +04:00
case XML_SCHEMA_FACET_MAXLENGTH :
2003-02-27 20:42:22 +03:00
case XML_SCHEMA_FACET_MINLENGTH : {
unsigned int len = 0 ;
2002-04-22 20:01:24 +04:00
2005-06-09 14:32:53 +04:00
if ( ( valType = = XML_SCHEMAS_QNAME ) | |
( valType = = XML_SCHEMAS_NOTATION ) )
return ( 0 ) ;
2005-03-16 19:29:18 +03:00
/*
* TODO : length , maxLength and minLength must be of type
* nonNegativeInteger only . Check if decimal is used somehow .
*/
2003-02-27 20:42:22 +03:00
if ( ( facet - > val = = NULL ) | |
2003-03-31 01:10:09 +04:00
( ( facet - > val - > type ! = XML_SCHEMAS_DECIMAL ) & &
( facet - > val - > type ! = XML_SCHEMAS_NNINTEGER ) ) | |
2023-11-07 23:08:01 +03:00
! xmlSchemaValDecimalIsInteger ( & facet - > val - > value . decimal ) ) {
2003-02-27 20:42:22 +03:00
return ( - 1 ) ;
}
2003-07-07 01:13:49 +04:00
if ( ( val ! = NULL ) & & ( val - > type = = XML_SCHEMAS_HEXBINARY ) )
2003-08-08 18:00:28 +04:00
len = val - > value . hex . total ;
2003-08-27 18:15:15 +04:00
else if ( ( val ! = NULL ) & & ( val - > type = = XML_SCHEMAS_BASE64BINARY ) )
len = val - > value . base64 . total ;
else {
2005-03-15 17:58:11 +03:00
switch ( valType ) {
2005-03-16 19:29:18 +03:00
case XML_SCHEMAS_STRING :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_NORMSTRING :
2005-03-16 19:29:18 +03:00
if ( ws = = XML_SCHEMA_WHITESPACE_UNKNOWN ) {
/*
* This is to ensure API compatibility with the old
* xmlSchemaValidateFacet ( ) . Anyway , this was and
* is not the correct handling .
* TODO : Get rid of this case somehow .
*/
if ( valType = = XML_SCHEMAS_STRING )
len = xmlUTF8Strlen ( value ) ;
else
len = xmlSchemaNormLen ( value ) ;
} else if ( value ! = NULL ) {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
len = xmlSchemaNormLen ( value ) ;
else
2012-09-11 09:26:36 +04:00
/*
2005-03-16 19:29:18 +03:00
* Should be OK for " preserve " as well .
*/
len = xmlUTF8Strlen ( value ) ;
}
break ;
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_IDREF :
2003-07-07 01:13:49 +04:00
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
case XML_SCHEMAS_NAME :
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
2004-06-29 21:04:39 +04:00
case XML_SCHEMAS_ANYURI :
2005-03-16 19:29:18 +03:00
if ( value ! = NULL )
2012-09-11 09:26:36 +04:00
len = xmlSchemaNormLen ( value ) ;
break ;
2003-07-07 01:13:49 +04:00
default :
2023-12-18 21:51:32 +03:00
/* TODO */
break ;
2012-09-11 09:26:36 +04:00
}
2003-02-27 20:42:22 +03:00
}
if ( facet - > type = = XML_SCHEMA_FACET_LENGTH ) {
2023-11-07 23:08:01 +03:00
if ( len ! = xmlSchemaGetFacetValueAsULong ( facet ) )
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_LENGTH_VALID ) ;
2003-02-27 20:42:22 +03:00
} else if ( facet - > type = = XML_SCHEMA_FACET_MINLENGTH ) {
2023-11-07 23:08:01 +03:00
if ( len < xmlSchemaGetFacetValueAsULong ( facet ) )
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_MINLENGTH_VALID ) ;
2023-11-07 23:08:01 +03:00
} else if ( len > xmlSchemaGetFacetValueAsULong ( facet ) ) {
return ( XML_SCHEMAV_CVC_MAXLENGTH_VALID ) ;
2002-04-22 20:01:24 +04:00
}
2003-02-27 20:42:22 +03:00
break ;
}
2003-07-07 01:13:49 +04:00
case XML_SCHEMA_FACET_TOTALDIGITS :
case XML_SCHEMA_FACET_FRACTIONDIGITS :
if ( ( facet - > val = = NULL ) | |
2005-11-07 17:02:44 +03:00
( ( facet - > val - > type ! = XML_SCHEMAS_PINTEGER ) & &
2003-07-07 01:13:49 +04:00
( facet - > val - > type ! = XML_SCHEMAS_NNINTEGER ) ) | |
2023-11-07 23:08:01 +03:00
! xmlSchemaValDecimalIsInteger ( & facet - > val - > value . decimal ) ) {
2003-07-07 01:13:49 +04:00
return ( - 1 ) ;
}
if ( ( val = = NULL ) | |
( ( val - > type ! = XML_SCHEMAS_DECIMAL ) & &
( val - > type ! = XML_SCHEMAS_INTEGER ) & &
( val - > type ! = XML_SCHEMAS_NPINTEGER ) & &
( val - > type ! = XML_SCHEMAS_NINTEGER ) & &
( val - > type ! = XML_SCHEMAS_NNINTEGER ) & &
( val - > type ! = XML_SCHEMAS_PINTEGER ) & &
( val - > type ! = XML_SCHEMAS_INT ) & &
( val - > type ! = XML_SCHEMAS_UINT ) & &
( val - > type ! = XML_SCHEMAS_LONG ) & &
( val - > type ! = XML_SCHEMAS_ULONG ) & &
( val - > type ! = XML_SCHEMAS_SHORT ) & &
( val - > type ! = XML_SCHEMAS_USHORT ) & &
( val - > type ! = XML_SCHEMAS_BYTE ) & &
( val - > type ! = XML_SCHEMAS_UBYTE ) ) ) {
return ( - 1 ) ;
}
if ( facet - > type = = XML_SCHEMA_FACET_TOTALDIGITS ) {
2023-11-07 23:08:01 +03:00
if ( xmlSchemaValDecimalGetSignificantDigitCount ( & val - > value . decimal ) > xmlSchemaGetFacetValueAsULong ( facet ) )
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_TOTALDIGITS_VALID ) ;
2003-07-07 01:13:49 +04:00
} else if ( facet - > type = = XML_SCHEMA_FACET_FRACTIONDIGITS ) {
2023-11-07 23:08:01 +03:00
if ( ( xmlSchemaValDecimalIsInteger ( & val - > value . decimal ) ? 0 : val - > value . decimal . fractionalPlaces ) > xmlSchemaGetFacetValueAsULong ( facet ) )
2004-06-29 21:04:39 +04:00
return ( XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID ) ;
2003-07-07 01:13:49 +04:00
}
break ;
2002-04-16 19:50:10 +04:00
default :
2023-12-18 21:51:32 +03:00
/* TODO */
break ;
2002-04-16 19:50:10 +04:00
}
return ( 0 ) ;
2003-03-29 19:41:55 +03:00
2002-04-16 19:50:10 +04:00
}
2005-03-15 17:58:11 +03:00
/**
* xmlSchemaValidateFacet :
* @ base : the base type
* @ facet : the facet to check
* @ value : the lexical repr of the value to validate
* @ val : the precomputed value
*
* Check a value against a facet condition
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
int
2005-03-16 19:39:23 +03:00
xmlSchemaValidateFacet ( xmlSchemaTypePtr base ,
2005-03-15 17:58:11 +03:00
xmlSchemaFacetPtr facet ,
const xmlChar * value ,
xmlSchemaValPtr val )
{
/*
* This tries to ensure API compatibility regarding the old
* xmlSchemaValidateFacet ( ) and the new xmlSchemaValidateFacetInternal ( ) and
* xmlSchemaValidateFacetWhtsp ( ) .
*/
2005-03-16 19:39:23 +03:00
if ( val ! = NULL )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaValidateFacetInternal ( facet ,
2005-03-16 19:39:23 +03:00
XML_SCHEMA_WHITESPACE_UNKNOWN , val - > type , value , val ,
2005-03-15 17:58:11 +03:00
XML_SCHEMA_WHITESPACE_UNKNOWN ) ) ;
2005-03-16 19:39:23 +03:00
else if ( base ! = NULL )
2005-03-15 17:58:11 +03:00
return ( xmlSchemaValidateFacetInternal ( facet ,
2005-03-16 19:39:23 +03:00
XML_SCHEMA_WHITESPACE_UNKNOWN , base - > builtInType , value , val ,
2005-03-16 19:29:18 +03:00
XML_SCHEMA_WHITESPACE_UNKNOWN ) ) ;
2005-03-16 19:39:23 +03:00
return ( - 1 ) ;
2005-03-15 17:58:11 +03:00
}
/**
* xmlSchemaValidateFacetWhtsp :
* @ facet : the facet to check
* @ fws : the whitespace type of the facet ' s value
* @ valType : the built - in type of the value
* @ value : the lexical ( or normalized for pattern ) repr of the value to validate
* @ val : the precomputed value
* @ ws : the whitespace type of the value
*
* Check a value against a facet condition . This takes value normalization
* according to the specified whitespace types into account .
* Note that @ value needs to be the * normalized * value if the facet
* is of type " pattern " .
*
* Returns 0 if the element is schemas valid , a positive error code
* number otherwise and - 1 in case of internal or API error .
*/
int
xmlSchemaValidateFacetWhtsp ( xmlSchemaFacetPtr facet ,
xmlSchemaWhitespaceValueType fws ,
2012-09-11 09:26:36 +04:00
xmlSchemaValType valType ,
2005-03-15 17:58:11 +03:00
const xmlChar * value ,
2005-03-16 19:29:18 +03:00
xmlSchemaValPtr val ,
2005-03-15 17:58:11 +03:00
xmlSchemaWhitespaceValueType ws )
{
return ( xmlSchemaValidateFacetInternal ( facet , fws , valType ,
2005-03-16 19:29:18 +03:00
value , val , ws ) ) ;
2005-03-15 17:58:11 +03:00
}
2005-02-17 14:10:44 +03:00
/**
* xmlSchemaGetCanonValue :
* @ val : the precomputed value
* @ retValue : the returned value
*
2013-11-30 02:26:26 +04:00
* Get the canonical lexical representation of the value .
2005-04-18 14:57:04 +04:00
* The caller has to FREE the returned retValue .
*
2005-03-16 19:29:18 +03:00
* WARNING : Some value types are not supported yet , resulting
* in a @ retValue of " ??? " .
2012-09-11 09:26:36 +04:00
*
2005-04-18 14:57:04 +04:00
* TODO : XML Schema 1.0 does not define canonical representations
* for : duration , gYearMonth , gYear , gMonthDay , gMonth , gDay ,
* anyURI , QName , NOTATION . This will be fixed in XML Schema 1.1 .
*
2005-02-17 14:10:44 +03:00
*
2005-04-18 14:57:04 +04:00
* Returns 0 if the value could be built , 1 if the value type is
* not supported yet and - 1 in case of API errors .
2005-02-17 14:10:44 +03:00
*/
int
2005-02-19 21:27:14 +03:00
xmlSchemaGetCanonValue ( xmlSchemaValPtr val , const xmlChar * * retValue )
2005-02-17 14:10:44 +03:00
{
2005-02-19 21:27:14 +03:00
if ( ( retValue = = NULL ) | | ( val = = NULL ) )
2005-02-17 14:10:44 +03:00
return ( - 1 ) ;
* retValue = NULL ;
switch ( val - > type ) {
2005-03-16 19:29:18 +03:00
case XML_SCHEMAS_STRING :
if ( val - > value . str = = NULL )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " " ) ;
else
2012-09-11 09:26:36 +04:00
* retValue =
2005-03-16 19:29:18 +03:00
BAD_CAST xmlStrdup ( ( const xmlChar * ) val - > value . str ) ;
break ;
2005-02-17 14:10:44 +03:00
case XML_SCHEMAS_NORMSTRING :
2005-03-16 19:29:18 +03:00
if ( val - > value . str = = NULL )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " " ) ;
else {
* retValue = xmlSchemaWhiteSpaceReplace (
( const xmlChar * ) val - > value . str ) ;
if ( ( * retValue ) = = NULL )
* retValue = BAD_CAST xmlStrdup (
( const xmlChar * ) val - > value . str ) ;
}
break ;
2005-02-17 14:10:44 +03:00
case XML_SCHEMAS_TOKEN :
case XML_SCHEMAS_LANGUAGE :
case XML_SCHEMAS_NMTOKEN :
2012-09-11 09:26:36 +04:00
case XML_SCHEMAS_NAME :
2005-02-17 14:10:44 +03:00
case XML_SCHEMAS_NCNAME :
case XML_SCHEMAS_ID :
case XML_SCHEMAS_IDREF :
case XML_SCHEMAS_ENTITY :
2005-04-18 14:57:04 +04:00
case XML_SCHEMAS_NOTATION : /* Unclear */
case XML_SCHEMAS_ANYURI : /* Unclear */
2005-02-17 14:10:44 +03:00
if ( val - > value . str = = NULL )
2005-03-16 19:29:18 +03:00
return ( - 1 ) ;
2012-09-11 09:26:36 +04:00
* retValue =
2005-04-01 19:17:27 +04:00
BAD_CAST xmlSchemaCollapseString ( BAD_CAST val - > value . str ) ;
if ( * retValue = = NULL )
2012-09-11 09:26:36 +04:00
* retValue =
2005-04-01 19:17:27 +04:00
BAD_CAST xmlStrdup ( ( const xmlChar * ) val - > value . str ) ;
2005-03-16 19:29:18 +03:00
break ;
case XML_SCHEMAS_QNAME :
2005-04-18 14:57:04 +04:00
/* TODO: Unclear in XML Schema 1.0. */
2005-03-16 19:29:18 +03:00
if ( val - > value . qname . uri = = NULL ) {
* retValue = BAD_CAST xmlStrdup ( BAD_CAST val - > value . qname . name ) ;
return ( 0 ) ;
} else {
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " { " ) ;
* retValue = BAD_CAST xmlStrcat ( ( xmlChar * ) ( * retValue ) ,
BAD_CAST val - > value . qname . uri ) ;
* retValue = BAD_CAST xmlStrcat ( ( xmlChar * ) ( * retValue ) ,
BAD_CAST " } " ) ;
* retValue = BAD_CAST xmlStrcat ( ( xmlChar * ) ( * retValue ) ,
BAD_CAST val - > value . qname . uri ) ;
}
break ;
2023-11-07 23:08:01 +03:00
case XML_SCHEMAS_DECIMAL : {
xmlChar * start = val - > value . decimal . str ;
if ( start [ 0 ] = = ' + ' )
{
start + = 1 ;
}
* retValue = xmlStrdup ( start ) ;
2005-04-18 14:57:04 +04:00
}
break ;
case XML_SCHEMAS_INTEGER :
case XML_SCHEMAS_PINTEGER :
case XML_SCHEMAS_NPINTEGER :
case XML_SCHEMAS_NINTEGER :
case XML_SCHEMAS_NNINTEGER :
case XML_SCHEMAS_LONG :
case XML_SCHEMAS_BYTE :
case XML_SCHEMAS_SHORT :
case XML_SCHEMAS_INT :
case XML_SCHEMAS_UINT :
case XML_SCHEMAS_ULONG :
case XML_SCHEMAS_USHORT :
2023-11-07 23:08:01 +03:00
case XML_SCHEMAS_UBYTE : {
xmlChar * start = val - > value . decimal . str ;
/* 2 = sign+NULL */
size_t bufSize = val - > value . decimal . integralPlaces + 2 ;
if ( start [ 0 ] = = ' + ' )
{
start + = 1 ;
bufSize - = 1 ;
}
* retValue = xmlMalloc ( bufSize ) ;
if ( * retValue ) {
/* no need to limit string length in format, it will only print bufSize-1 chars anyways */
snprintf ( ( char * ) * retValue , bufSize , " %s " , start ) ;
}
2005-04-18 14:57:04 +04:00
}
break ;
case XML_SCHEMAS_BOOLEAN :
if ( val - > value . b )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " true " ) ;
else
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " false " ) ;
break ;
case XML_SCHEMAS_DURATION : {
char buf [ 100 ] ;
unsigned long year ;
unsigned long mon , day , hour = 0 , min = 0 ;
double sec = 0 , left ;
/* TODO: Unclear in XML Schema 1.0 */
/*
* TODO : This results in a normalized output of the value
* - which is NOT conformant to the spec -
* since the exact values of each property are not
* recoverable . Think about extending the structure to
* provide a field for every property .
*/
year = ( unsigned long ) FQUOTIENT ( labs ( val - > value . dur . mon ) , 12 ) ;
mon = labs ( val - > value . dur . mon ) - 12 * year ;
day = ( unsigned long ) FQUOTIENT ( fabs ( val - > value . dur . sec ) , 86400 ) ;
left = fabs ( val - > value . dur . sec ) - day * 86400 ;
if ( left > 0 ) {
hour = ( unsigned long ) FQUOTIENT ( left , 3600 ) ;
left = left - ( hour * 3600 ) ;
if ( left > 0 ) {
min = ( unsigned long ) FQUOTIENT ( left , 60 ) ;
sec = left - ( min * 60 ) ;
}
}
if ( ( val - > value . dur . mon < 0 ) | | ( val - > value . dur . sec < 0 ) )
snprintf ( buf , 100 , " P%luY%luM%luDT%luH%luM%.14gS " ,
year , mon , day , hour , min , sec ) ;
else
snprintf ( buf , 100 , " -P%luY%luM%luDT%luH%luM%.14gS " ,
year , mon , day , hour , min , sec ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
break ;
case XML_SCHEMAS_GYEAR : {
char buf [ 30 ] ;
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
snprintf ( buf , 30 , " %04ld " , val - > value . date . year ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
break ;
case XML_SCHEMAS_GMONTH : {
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
2006-10-11 16:32:51 +04:00
* retValue = xmlMalloc ( 6 ) ;
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-04-18 14:57:04 +04:00
snprintf ( ( char * ) * retValue , 6 , " --%02u " ,
val - > value . date . mon ) ;
}
break ;
case XML_SCHEMAS_GDAY : {
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
* retValue = xmlMalloc ( 6 ) ;
2006-10-11 16:32:51 +04:00
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-04-18 14:57:04 +04:00
snprintf ( ( char * ) * retValue , 6 , " ---%02u " ,
val - > value . date . day ) ;
}
2012-09-11 09:26:36 +04:00
break ;
2005-04-18 14:57:04 +04:00
case XML_SCHEMAS_GMONTHDAY : {
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
* retValue = xmlMalloc ( 8 ) ;
2006-10-11 16:32:51 +04:00
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-04-18 14:57:04 +04:00
snprintf ( ( char * ) * retValue , 8 , " --%02u-%02u " ,
val - > value . date . mon , val - > value . date . day ) ;
}
break ;
case XML_SCHEMAS_GYEARMONTH : {
char buf [ 35 ] ;
/* TODO: Unclear in XML Schema 1.0 */
/* TODO: What to do with the timezone? */
if ( val - > value . date . year < 0 )
snprintf ( buf , 35 , " -%04ld-%02u " ,
2012-09-11 09:26:36 +04:00
labs ( val - > value . date . year ) ,
2005-04-18 14:57:04 +04:00
val - > value . date . mon ) ;
else
snprintf ( buf , 35 , " %04ld-%02u " ,
val - > value . date . year , val - > value . date . mon ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
2012-09-11 09:26:36 +04:00
break ;
2005-04-18 14:57:04 +04:00
case XML_SCHEMAS_TIME :
{
char buf [ 30 ] ;
if ( val - > value . date . tz_flag ) {
xmlSchemaValPtr norm ;
norm = xmlSchemaDateNormalize ( val , 0 ) ;
if ( norm = = NULL )
return ( - 1 ) ;
2012-09-11 09:26:36 +04:00
/*
* TODO : Check if " %.14g " is portable .
2005-04-18 14:57:04 +04:00
*/
snprintf ( buf , 30 ,
" %02u:%02u:%02.14gZ " ,
norm - > value . date . hour ,
norm - > value . date . min ,
norm - > value . date . sec ) ;
xmlSchemaFreeValue ( norm ) ;
} else {
snprintf ( buf , 30 ,
" %02u:%02u:%02.14g " ,
val - > value . date . hour ,
val - > value . date . min ,
val - > value . date . sec ) ;
}
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
2012-09-11 09:26:36 +04:00
}
2005-04-18 14:57:04 +04:00
break ;
case XML_SCHEMAS_DATE :
{
char buf [ 30 ] ;
if ( val - > value . date . tz_flag ) {
xmlSchemaValPtr norm ;
norm = xmlSchemaDateNormalize ( val , 0 ) ;
if ( norm = = NULL )
return ( - 1 ) ;
/*
* TODO : Append the canonical value of the
* recoverable timezone and not " Z " .
*/
snprintf ( buf , 30 ,
2020-01-31 22:16:37 +03:00
" %04ld-%02u-%02uZ " ,
2005-04-18 14:57:04 +04:00
norm - > value . date . year , norm - > value . date . mon ,
norm - > value . date . day ) ;
xmlSchemaFreeValue ( norm ) ;
} else {
snprintf ( buf , 30 ,
2020-01-31 22:16:37 +03:00
" %04ld-%02u-%02u " ,
2005-04-18 14:57:04 +04:00
val - > value . date . year , val - > value . date . mon ,
val - > value . date . day ) ;
}
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
2012-09-11 09:26:36 +04:00
}
2005-04-18 14:57:04 +04:00
break ;
case XML_SCHEMAS_DATETIME :
{
char buf [ 50 ] ;
if ( val - > value . date . tz_flag ) {
xmlSchemaValPtr norm ;
norm = xmlSchemaDateNormalize ( val , 0 ) ;
if ( norm = = NULL )
return ( - 1 ) ;
/*
* TODO : Check if " %.14g " is portable .
*/
snprintf ( buf , 50 ,
2020-01-31 22:16:37 +03:00
" %04ld-%02u-%02uT%02u:%02u:%02.14gZ " ,
2005-04-18 14:57:04 +04:00
norm - > value . date . year , norm - > value . date . mon ,
norm - > value . date . day , norm - > value . date . hour ,
norm - > value . date . min , norm - > value . date . sec ) ;
xmlSchemaFreeValue ( norm ) ;
} else {
snprintf ( buf , 50 ,
2020-01-31 22:16:37 +03:00
" %04ld-%02u-%02uT%02u:%02u:%02.14g " ,
2005-04-18 14:57:04 +04:00
val - > value . date . year , val - > value . date . mon ,
val - > value . date . day , val - > value . date . hour ,
val - > value . date . min , val - > value . date . sec ) ;
}
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
break ;
case XML_SCHEMAS_HEXBINARY :
* retValue = BAD_CAST xmlStrdup ( BAD_CAST val - > value . hex . str ) ;
break ;
case XML_SCHEMAS_BASE64BINARY :
/*
* TODO : Is the following spec piece implemented ? :
* SPEC : " Note: For some values the canonical form defined
* above does not conform to [ RFC 2045 ] , which requires breaking
* with linefeeds at appropriate intervals . "
*/
* retValue = BAD_CAST xmlStrdup ( BAD_CAST val - > value . base64 . str ) ;
break ;
case XML_SCHEMAS_FLOAT : {
2012-09-11 09:26:36 +04:00
char buf [ 30 ] ;
/*
2005-04-18 14:57:04 +04:00
* | m | < 16777216 , - 149 < = e < = 104.
* TODO : Handle , NaN , INF , - INF . The format is not
* yet conformant . The c type float does not cover
* the whole range .
*/
snprintf ( buf , 30 , " %01.14e " , val - > value . f ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
break ;
case XML_SCHEMAS_DOUBLE : {
char buf [ 40 ] ;
/* |m| < 9007199254740992, -1075 <= e <= 970 */
/*
* TODO : Handle , NaN , INF , - INF . The format is not
* yet conformant . The c type float does not cover
* the whole range .
*/
snprintf ( buf , 40 , " %01.14e " , val - > value . d ) ;
* retValue = BAD_CAST xmlStrdup ( BAD_CAST buf ) ;
}
2012-09-11 09:26:36 +04:00
break ;
2005-02-17 14:10:44 +03:00
default :
2005-03-16 19:29:18 +03:00
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " ??? " ) ;
2005-04-18 14:57:04 +04:00
return ( 1 ) ;
2005-02-17 14:10:44 +03:00
}
2006-10-11 16:32:51 +04:00
if ( * retValue = = NULL )
return ( - 1 ) ;
2005-03-16 19:29:18 +03:00
return ( 0 ) ;
}
2005-04-18 14:57:04 +04:00
/**
* xmlSchemaGetCanonValueWhtsp :
* @ val : the precomputed value
* @ retValue : the returned value
* @ ws : the whitespace type of the value
*
2013-11-30 02:26:26 +04:00
* Get the canonical representation of the value .
2005-04-18 14:57:04 +04:00
* The caller has to free the returned @ retValue .
*
* Returns 0 if the value could be built , 1 if the value type is
* not supported yet and - 1 in case of API errors .
*/
int
xmlSchemaGetCanonValueWhtsp ( xmlSchemaValPtr val ,
const xmlChar * * retValue ,
xmlSchemaWhitespaceValueType ws )
{
if ( ( retValue = = NULL ) | | ( val = = NULL ) )
return ( - 1 ) ;
if ( ( ws = = XML_SCHEMA_WHITESPACE_UNKNOWN ) | |
( ws > XML_SCHEMA_WHITESPACE_COLLAPSE ) )
return ( - 1 ) ;
* retValue = NULL ;
switch ( val - > type ) {
case XML_SCHEMAS_STRING :
if ( val - > value . str = = NULL )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " " ) ;
else if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
* retValue = xmlSchemaCollapseString ( val - > value . str ) ;
else if ( ws = = XML_SCHEMA_WHITESPACE_REPLACE )
* retValue = xmlSchemaWhiteSpaceReplace ( val - > value . str ) ;
if ( ( * retValue ) = = NULL )
* retValue = BAD_CAST xmlStrdup ( val - > value . str ) ;
break ;
case XML_SCHEMAS_NORMSTRING :
if ( val - > value . str = = NULL )
* retValue = BAD_CAST xmlStrdup ( BAD_CAST " " ) ;
else {
if ( ws = = XML_SCHEMA_WHITESPACE_COLLAPSE )
* retValue = xmlSchemaCollapseString ( val - > value . str ) ;
else
* retValue = xmlSchemaWhiteSpaceReplace ( val - > value . str ) ;
if ( ( * retValue ) = = NULL )
* retValue = BAD_CAST xmlStrdup ( val - > value . str ) ;
}
break ;
default :
return ( xmlSchemaGetCanonValue ( val , retValue ) ) ;
2012-09-11 09:26:36 +04:00
}
2005-04-18 14:57:04 +04:00
return ( 0 ) ;
}
2005-04-01 21:15:17 +04:00
/**
* xmlSchemaGetValType :
* @ val : a schemas value
*
* Accessor for the type of a value
*
* Returns the xmlSchemaValType of the value
*/
2005-03-16 19:29:18 +03:00
xmlSchemaValType
xmlSchemaGetValType ( xmlSchemaValPtr val )
{
2005-04-01 21:15:17 +04:00
if ( val = = NULL )
return ( XML_SCHEMAS_UNKNOWN ) ;
2005-03-16 19:29:18 +03:00
return ( val - > type ) ;
2005-02-17 14:10:44 +03:00
}
2002-04-16 19:50:10 +04:00
# endif /* LIBXML_SCHEMAS_ENABLED */