|
@@ -33,7 +33,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
# include <windows.h>
|
|
|
#endif // _WIN32
|
|
|
|
|
|
-#define DEBUG_HEADER_NAME
|
|
|
|
|
|
BEGIN_ODDLPARSER_NS
|
|
|
|
|
@@ -74,15 +73,26 @@ const char *getTypeToken( Value::ValueType type ) {
|
|
|
|
|
|
static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
|
|
|
std::stringstream stream;
|
|
|
- stream << "Invalid token " << *in << ", " << exp << " expected." << std::endl;
|
|
|
+ stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl;
|
|
|
+ std::string full(in);
|
|
|
+ std::string part(full.substr(0,50));
|
|
|
+ stream << part;
|
|
|
callback( ddl_error_msg, stream.str() );
|
|
|
}
|
|
|
|
|
|
static bool isIntegerType( Value::ValueType integerType ) {
|
|
|
- if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 &&
|
|
|
+ if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 &&
|
|
|
integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
|
|
|
return false;
|
|
|
}
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+static bool isUnsignedIntegerType( Value::ValueType integerType ) {
|
|
|
+ if( integerType != Value::ddl_unsigned_int8 && integerType != Value::ddl_unsigned_int16 &&
|
|
|
+ integerType != Value::ddl_unsigned_int32 && integerType != Value::ddl_unsigned_int64 ) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -193,7 +203,7 @@ bool OpenDDLParser::parse() {
|
|
|
if( m_buffer.empty() ) {
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
normalizeBuffer( m_buffer );
|
|
|
|
|
|
m_context = new Context;
|
|
@@ -206,6 +216,9 @@ bool OpenDDLParser::parse() {
|
|
|
size_t pos( current - &m_buffer[ 0 ] );
|
|
|
while( pos < m_buffer.size() ) {
|
|
|
current = parseNextNode( current, end );
|
|
|
+ if(current==ddl_nullptr) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
pos = current - &m_buffer[ 0 ];
|
|
|
}
|
|
|
return true;
|
|
@@ -215,11 +228,9 @@ bool OpenDDLParser::exportContext( Context *ctx, const std::string &filename ) {
|
|
|
if( ddl_nullptr == ctx ) {
|
|
|
return false;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
OpenDDLExport myExporter;
|
|
|
return myExporter.exportContext( ctx, filename );
|
|
|
-
|
|
|
- return false;
|
|
|
}
|
|
|
|
|
|
char *OpenDDLParser::parseNextNode( char *in, char *end ) {
|
|
@@ -229,12 +240,15 @@ char *OpenDDLParser::parseNextNode( char *in, char *end ) {
|
|
|
return in;
|
|
|
}
|
|
|
|
|
|
+#ifdef DEBUG_HEADER_NAME
|
|
|
static void dumpId( Identifier *id ) {
|
|
|
if( ddl_nullptr != id ) {
|
|
|
- if ( ddl_nullptr != id->m_text.m_buffer ) { }
|
|
|
+ if ( ddl_nullptr != id->m_text.m_buffer ) {
|
|
|
std::cout << id->m_text.m_buffer << std::endl;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
|
|
if( ddl_nullptr == in || in == end ) {
|
|
@@ -244,7 +258,7 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
|
|
Identifier *id( ddl_nullptr );
|
|
|
in = OpenDDLParser::parseIdentifier( in, end, &id );
|
|
|
|
|
|
-#ifdef DEBUG_HEADER_NAME
|
|
|
+#ifdef DEBUG_HEADER_NAME
|
|
|
dumpId( id );
|
|
|
#endif // DEBUG_HEADER_NAME
|
|
|
|
|
@@ -260,9 +274,9 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
|
|
|
|
|
|
if( *in != Grammar::CommaSeparator[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] ) {
|
|
|
logInvalidTokenError( in, Grammar::ClosePropertyToken, m_logCallback );
|
|
|
- return in;
|
|
|
+ return ddl_nullptr;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if( ddl_nullptr != prop && *in != Grammar::CommaSeparator[ 0 ] ) {
|
|
|
if( ddl_nullptr == first ) {
|
|
|
first = prop;
|
|
@@ -311,16 +325,19 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
|
|
|
// loop over all children ( data and nodes )
|
|
|
do {
|
|
|
in = parseStructureBody( in, end, error );
|
|
|
+ if(in == ddl_nullptr){
|
|
|
+ return ddl_nullptr;
|
|
|
+ }
|
|
|
} while ( *in != '}' );
|
|
|
in++;
|
|
|
} else {
|
|
|
in++;
|
|
|
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
|
|
|
error = true;
|
|
|
- return in;
|
|
|
+ return ddl_nullptr;
|
|
|
}
|
|
|
in = lookForNextToken( in, end );
|
|
|
-
|
|
|
+
|
|
|
// pop node from stack after successful parsing
|
|
|
if( !error ) {
|
|
|
popNode();
|
|
@@ -375,7 +392,7 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
|
|
|
setNodeValues( top(), values );
|
|
|
setNodeReferences( top(), refs );
|
|
|
} else if( arrayLen > 1 ) {
|
|
|
- in = parseDataArrayList( in, end, &dtArrayList );
|
|
|
+ in = parseDataArrayList( in, end, type, &dtArrayList );
|
|
|
setNodeDataArrayList( top(), dtArrayList );
|
|
|
} else {
|
|
|
std::cerr << "0 for array is invalid." << std::endl;
|
|
@@ -386,6 +403,7 @@ char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
|
|
|
in = lookForNextToken( in, end );
|
|
|
if( *in != '}' ) {
|
|
|
logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback );
|
|
|
+ return ddl_nullptr;
|
|
|
} else {
|
|
|
//in++;
|
|
|
}
|
|
@@ -420,7 +438,7 @@ DDLNode *OpenDDLParser::top() {
|
|
|
if( m_stack.empty() ) {
|
|
|
return ddl_nullptr;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
DDLNode *top( m_stack.back() );
|
|
|
return top;
|
|
|
}
|
|
@@ -479,7 +497,7 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
|
|
|
if( *in == '%' ) {
|
|
|
ntype = LocalName;
|
|
|
}
|
|
|
-
|
|
|
+ in++;
|
|
|
Name *currentName( ddl_nullptr );
|
|
|
Identifier *id( ddl_nullptr );
|
|
|
in = parseIdentifier( in, end, &id );
|
|
@@ -489,7 +507,7 @@ char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
|
|
|
*name = currentName;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
return in;
|
|
|
}
|
|
|
|
|
@@ -501,7 +519,7 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) {
|
|
|
|
|
|
// ignore blanks
|
|
|
in = lookForNextToken( in, end );
|
|
|
-
|
|
|
+
|
|
|
// staring with a number is forbidden
|
|
|
if( isNumeric<const char>( *in ) ) {
|
|
|
return in;
|
|
@@ -510,11 +528,11 @@ char *OpenDDLParser::parseIdentifier( char *in, char *end, Identifier **id ) {
|
|
|
// get size of id
|
|
|
size_t idLen( 0 );
|
|
|
char *start( in );
|
|
|
- while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != Grammar::OpenPropertyToken[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] ) {
|
|
|
+ while( !isSeparator( *in ) && !isNewLine( *in ) && ( in != end ) && *in != Grammar::OpenPropertyToken[ 0 ] && *in != Grammar::ClosePropertyToken[ 0 ] && *in != '$' ) {
|
|
|
++in;
|
|
|
++idLen;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
const size_t len( idLen );
|
|
|
Identifier *newId = new Identifier( start, len );
|
|
|
*id = newId;
|
|
@@ -631,7 +649,7 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
|
|
|
return in;
|
|
|
}
|
|
|
|
|
|
- if( !isIntegerType( integerType ) ) {
|
|
|
+ if( !(isIntegerType( integerType ) || isUnsignedIntegerType(integerType)) ) {
|
|
|
return in;
|
|
|
}
|
|
|
|
|
@@ -642,7 +660,13 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
|
|
|
}
|
|
|
|
|
|
if( isNumeric( *start ) ) {
|
|
|
- const int value( atoi( start ) );
|
|
|
+#ifdef OPENDDL_NO_USE_CPP11
|
|
|
+ const int64 value( atol( start ) ); // maybe not really 64bit as atoll is but exists without c++11
|
|
|
+ const uint64 uvalue( strtoul( start,ddl_nullptr,10 ) );
|
|
|
+#else
|
|
|
+ const int64 value( atoll( start ) );
|
|
|
+ const uint64 uvalue( strtoull( start,ddl_nullptr,10 ) );
|
|
|
+#endif
|
|
|
*integer = ValueAllocator::allocPrimData( integerType );
|
|
|
switch( integerType ) {
|
|
|
case Value::ddl_int8:
|
|
@@ -657,15 +681,27 @@ char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer,
|
|
|
case Value::ddl_int64:
|
|
|
( *integer )->setInt64( ( int64 ) value );
|
|
|
break;
|
|
|
+ case Value::ddl_unsigned_int8:
|
|
|
+ ( *integer )->setUnsignedInt8( (uint8) uvalue );
|
|
|
+ break;
|
|
|
+ case Value::ddl_unsigned_int16:
|
|
|
+ ( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
|
|
|
+ break;
|
|
|
+ case Value::ddl_unsigned_int32:
|
|
|
+ ( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
|
|
|
+ break;
|
|
|
+ case Value::ddl_unsigned_int64:
|
|
|
+ ( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
|
|
|
+ break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
return in;
|
|
|
}
|
|
|
|
|
|
-char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating ) {
|
|
|
+char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType) {
|
|
|
*floating = ddl_nullptr;
|
|
|
if( ddl_nullptr == in || in == end ) {
|
|
|
return in;
|
|
@@ -690,9 +726,16 @@ char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating
|
|
|
}
|
|
|
|
|
|
if( ok ) {
|
|
|
- const float value( ( float ) atof( start ) );
|
|
|
- *floating = ValueAllocator::allocPrimData( Value::ddl_float );
|
|
|
- ( *floating )->setFloat( value );
|
|
|
+ if(floatType == Value::ddl_double)
|
|
|
+ {
|
|
|
+ const double value( atof( start ) );
|
|
|
+ *floating = ValueAllocator::allocPrimData( Value::ddl_double );
|
|
|
+ ( *floating )->setDouble( value );
|
|
|
+ } else {
|
|
|
+ const float value( ( float ) atof( start ) );
|
|
|
+ *floating = ValueAllocator::allocPrimData( Value::ddl_float );
|
|
|
+ ( *floating )->setFloat( value );
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return in;
|
|
@@ -813,7 +856,7 @@ char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
|
|
|
( *prop )->m_ref = ref;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return in;
|
|
@@ -856,12 +899,27 @@ char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type,
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- if (Value::ddl_int32 == type) {
|
|
|
- in = parseIntegerLiteral( in, end, ¤t );
|
|
|
- } else if (Value::ddl_float == type) {
|
|
|
- in = parseFloatingLiteral( in, end, ¤t );
|
|
|
- } else if (Value::ddl_string == type) {
|
|
|
- in = parseStringLiteral( in, end, ¤t );
|
|
|
+ switch(type){
|
|
|
+ case Value::ddl_int8:
|
|
|
+ case Value::ddl_int16:
|
|
|
+ case Value::ddl_int32:
|
|
|
+ case Value::ddl_int64:
|
|
|
+ case Value::ddl_unsigned_int8:
|
|
|
+ case Value::ddl_unsigned_int16:
|
|
|
+ case Value::ddl_unsigned_int32:
|
|
|
+ case Value::ddl_unsigned_int64:
|
|
|
+ in = parseIntegerLiteral( in, end, ¤t, type);
|
|
|
+ break;
|
|
|
+ case Value::ddl_half:
|
|
|
+ case Value::ddl_float:
|
|
|
+ case Value::ddl_double:
|
|
|
+ in = parseFloatingLiteral( in, end, ¤t, type);
|
|
|
+ break;
|
|
|
+ case Value::ddl_string:
|
|
|
+ in = parseStringLiteral( in, end, ¤t );
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -895,7 +953,7 @@ static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues
|
|
|
return dataList;
|
|
|
|
|
|
}
|
|
|
-char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **dataList ) {
|
|
|
+char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type, DataArrayList **dataList ) {
|
|
|
*dataList = ddl_nullptr;
|
|
|
if( ddl_nullptr == in || in == end ) {
|
|
|
return in;
|
|
@@ -910,7 +968,7 @@ char *OpenDDLParser::parseDataArrayList( char *in, char *end, DataArrayList **da
|
|
|
do {
|
|
|
size_t numRefs( 0 ), numValues( 0 );
|
|
|
currentValue = ddl_nullptr;
|
|
|
- Value::ValueType type( Value::ddl_none );
|
|
|
+
|
|
|
in = parseDataList( in, end, type, ¤tValue, numValues, &refs, numRefs );
|
|
|
if( ddl_nullptr != currentValue ) {
|
|
|
if( ddl_nullptr == prev ) {
|