@ -113,7 +113,7 @@ SpaceParser::Status SpaceParser::Parse(const char * file_name)
reading_from_file = true ;
file . clear ( ) ;
file . open ( file_name ) ;
file . open ( file_name , std : : ios_base : : binary | std : : ios_base : : in ) ;
if ( file )
{
@ -209,7 +209,7 @@ void SpaceParser::Parse()
if ( status = = ok & & space ! = root_space )
{
// last closing a space characters ')' are missing
// last closing ')' characters are missing (closing a space)
status = syntax_error ;
}
}
@ -225,16 +225,18 @@ void SpaceParser::ParseLoop()
}
else
{
ReadVariable ( ) ;
ReadKey ( ) ;
SkipWhite ( ) ;
if ( lastc = = list_start )
{
SpaceStarts ( ) ;
}
else
if ( lastc = = separator & & ! variable . empty ( ) )
if ( lastc = = separator )
{
ReadAddValue ( ) ;
ReadValue ( ) ;
AddKeyValuePair ( ) ;
}
else
{
@ -258,7 +260,11 @@ void SpaceParser::SpaceEnds()
else
{
space = space - > parent ;
ReadChar ( ) ;
ReadChar ( ) ; // skipping closing space character ')'
SkipWhite ( ) ;
if ( lastc ! = - 1 & & lastc ! = ' \n ' )
status = syntax_error ;
}
}
@ -268,40 +274,19 @@ void SpaceParser::SpaceStarts()
Space * new_space = new Space ( ) ;
space - > spaces . push_back ( new_space ) ;
new_space - > parent = space ;
new_space - > name = variable ;
new_space - > name = key ;
space = new_space ;
ReadChar ( ) ;
ReadChar ( ) ; // skipping space starts character ')'
}
void SpaceParser : : ReadAddValue ( )
{
ReadChar ( ) ; // skipping separator '='
if ( ReadValue ( ) )
{
AddOption ( ) ;
}
else
{
status = syntax_error ;
}
}
bool SpaceParser : : IsVariableChar ( int c )
{
if ( ( c > = ' a ' & & c < = ' z ' ) | |
( c > = ' A ' & & c < = ' Z ' ) | |
( c > = ' 0 ' & & c < = ' 9 ' ) | |
c = = ' . ' | | c = = ' , ' | | c = = ' _ ' )
return true ;
return false ;
}
/*
those white characters here should be the same as in space . h
*/
bool SpaceParser : : IsWhite ( int c )
{
// dont use '\n' here
@ -380,27 +365,6 @@ std::wstring::size_type i;
void SpaceParser : : AddOption ( )
{
if ( value . empty ( ) & & skip_empty )
{
DeleteFromTable ( variable ) ;
DeleteFromTableSingle ( variable ) ;
return ;
}
if ( split_single & & value . size ( ) = = 1 )
{
space - > table_single [ variable ] = value [ 0 ] ;
DeleteFromTable ( variable ) ;
}
else
{
space - > table [ variable ] = value ;
DeleteFromTableSingle ( variable ) ;
}
}
void SpaceParser : : DeleteFromTable ( const std : : wstring & var )
@ -423,138 +387,155 @@ void SpaceParser::DeleteFromTableSingle(const std::wstring & var)
void SpaceParser : : ReadVariable ( )
void SpaceParser : : ReadTokenQuoted ( )
{
variable . clear ( ) ;
SkipWhite ( ) ;
while ( IsVariableChar ( lastc ) )
ReadChar ( ) ; // skipping the first quotation mark
while ( lastc ! = - 1 & & ( char_was_escaped | | lastc ! = ' " ' ) )
{
variable + = lastc ;
token + = static_cast < wchar_t > ( lastc ) ;
ReadChar ( ) ;
}
SkipWhite ( ) ;
if ( ! char_was_escaped & & lastc = = ' " ' )
ReadChar ( ) ; // skipping the last quotation mark
else
status = syntax_error ;
}
void SpaceParser : : ReadTokenSingle ( bool white_delimit , bool new_line_delimit , int delimit1 , int delimit2 )
{
while ( true )
{
if ( lastc = = commentary )
SkipLine ( ) ;
if ( lastc = = - 1 | |
( delimit1 ! = - 1 & & lastc = = delimit1 ) | |
( delimit2 ! = - 1 & & lastc = = delimit2 ) | |
( white_delimit & & IsWhite ( lastc ) ) | |
( new_line_delimit & & lastc = = ' \n ' ) )
{
break ;
}
token + = static_cast < wchar_t > ( lastc ) ;
ReadChar ( ) ;
}
bool SpaceParser : : ReadValue ( )
Trim ( token ) ;
}
void SpaceParser : : ReadToken ( bool white_delimit , bool new_line_delimit , int delimit1 , int delimit2 )
{
value . clear ( ) ;
token . clear ( ) ;
SkipWhite ( ) ;
if ( lastc = = list_start )
return ReadValueList ( ) ;
if ( ! char_was_escaped & & lastc = = ' " ' )
ReadTokenQuoted ( ) ;
else
return ReadValueNoList ( ) ;
ReadTokenSingle ( white_delimit , new_line_delimit , delimit1 , delimit2 ) ;
}
void SpaceParser : : ReadKey ( )
{
ReadToken ( false , true , separator , list_start ) ;
key = token ;
SkipWhite ( ) ;
}
bool SpaceParser : : ReadValueList ( )
void SpaceParser : : ReadValueList ( )
{
ReadChar ( ) ; // skipping first list character '('
SkipWhiteLines ( ) ; // lists can be split into several lines
ReadChar ( ) ; // skipping the first list character ') '
SkipWhiteLines ( ) ;
while ( lastc ! = - 1 & & lastc ! = list_end )
{
if ( ! ReadValueNoList ( true ) )
return false ;
ReadToken ( true , true , list_delimiter , list_end ) ;
value . push_back ( token ) ;
SkipWhiteLines ( ) ;
if ( lastc = = list_delimiter )
{
ReadChar ( ) ;
SkipWhiteLines ( ) ;
}
}
SkipWhiteLines ( ) ;
if ( lastc = = list_end )
{
ReadChar ( ) ; // skipping the last list character ')'
SkipWhite ( ) ;
// there cannot be anything after ')' character
if ( lastc ! = - 1 & & lastc ! = ' \n ' )
status = syntax_error ;
}
else
{
status = syntax_error ; // missing one ')'
}
}
if ( lastc ! = list_end )
return false ;
ReadChar ( ) ; // skipping last list character ')'
void SpaceParser : : ReadValueSingle ( )
{
SkipWhite ( ) ;
ReadToken ( false , true , - 1 , - 1 ) ;
value . push_back ( token ) ;
SkipWhite ( ) ;
return true ;
if ( lastc ! = - 1 & & lastc ! = ' \n ' )
status = syntax_error ;
}
bool SpaceParser : : ReadValueNoList ( bool use_list_delimiter )
void SpaceParser : : ReadValue ( )
{
bool res ;
value_item . clear ( ) ;
if ( lastc = = ' " ' )
{
res = ReadValueQuoted ( ) ; // quoted value
ReadChar ( ) ; // skipping separator '='
value . clear ( ) ;
SkipWhite ( ) ;
if ( res )
value . push_back ( value_item ) ;
}
if ( lastc = = ' ( ' )
ReadValueList ( ) ;
else
{
res = ReadValueSimple ( use_list_delimiter ) ;
ReadValueSingle ( ) ;
if ( res & & ! value_item . empty ( ) )
value . push_back ( value_item ) ;
}
return res ;
SkipWhiteLines ( ) ;
}
bool SpaceParser : : ReadValueQuoted ( )
void SpaceParser : : AddKeyValuePair ( )
{
ReadChar ( ) ; // skipping the first quote
// !! IMPROVE ME
// add some other escaped characters especialy \0 (the serializator is working that way now)
if ( value . empty ( ) & & skip_empty )
{
DeleteFromTable ( key ) ;
DeleteFromTableSingle ( key ) ;
return ;
}
while ( lastc ! = ' " ' & & lastc ! = - 1 )
if( split_single & & value . size ( ) = = 1 )
{
if ( use_escape_char & & lastc = = ' \\ ' )
ReadChar ( ) ;
value_item + = lastc ;
ReadChar ( ) ;
space - > table_single [ key ] = value [ 0 ] ;
DeleteFromTable ( key ) ;
}
else
{
space - > table [ key ] = value ;
DeleteFromTableSingle ( key ) ;
}
if ( lastc ! = ' " ' )
return false ;
ReadChar ( ) ; // skipping the last quote
SkipWhite ( ) ;
return true ;
}
bool SpaceParser : : ReadValueSimple ( bool use_list_delimiter )
{
int list_delimiter1 = - 1 ;
int list_delimiter2 = - 1 ;
if ( use_list_delimiter )
list_delimiter1 = list_delimiter ;
if ( use_list_delimiter | | space ! = root_space )
list_delimiter2 = list_end ;
while ( lastc ! = - 1 & & lastc ! = ' \n ' & & lastc ! = commentary & &
lastc ! = list_delimiter1 & & lastc ! = list_delimiter2 )
{
value_item + = lastc ;
ReadChar ( ) ;
}
Trim ( value_item ) ;
SkipWhite ( ) ;
return true ;
}
int SpaceParser : : ReadUTF8Char ( )
@ -651,7 +632,7 @@ return lastc;
}
int SpaceParser : : ReadChar ( )
int SpaceParser : : ReadChar NoEscape ( )
{
if ( reading_from_file )
{
@ -677,6 +658,31 @@ int SpaceParser::ReadChar()
}
int SpaceParser : : ReadChar ( )
{
char_was_escaped = false ;
ReadCharNoEscape ( ) ;
if ( use_escape_char & & lastc = = ' \\ ' )
{
char_was_escaped = true ;
ReadCharNoEscape ( ) ;
switch ( lastc )
{
case ' 0 ' : lastc = 0 ; break ;
case ' n ' : lastc = ' \n ' ; break ;
case ' \\ ' : lastc = ' \\ ' ; break ;
case ' r ' : lastc = ' \r ' ; break ;
case ' t ' : lastc = ' \t ' ; break ;
case ' " ' : lastc = ' " ' ; break ;
}
}
return lastc ;
}
} // namespace