209 lines
2.5 KiB
C++
209 lines
2.5 KiB
C++
|
/*
|
||
|
* This file is a part of CMSLU -- Content Management System like Unix
|
||
|
* and is not publicly distributed
|
||
|
*
|
||
|
* Copyright (c) 2008, Tomasz Sowa
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "confparser.h"
|
||
|
|
||
|
|
||
|
ConfParser::ConfParser()
|
||
|
{
|
||
|
separator = '=';
|
||
|
commentary = '#';
|
||
|
}
|
||
|
|
||
|
|
||
|
ConfParser::Status ConfParser::Parse(const char * file_name)
|
||
|
{
|
||
|
file.open( file_name );
|
||
|
|
||
|
if( !file )
|
||
|
return cant_open_file;
|
||
|
|
||
|
line = 1;
|
||
|
table.clear();
|
||
|
ReadChar();
|
||
|
status = ParseFile();
|
||
|
|
||
|
file.close();
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
ConfParser::Status ConfParser::ParseFile()
|
||
|
{
|
||
|
while( lastc != -1 )
|
||
|
{
|
||
|
if( ReadVariable() )
|
||
|
{
|
||
|
if( lastc != separator )
|
||
|
return syntax_error;
|
||
|
|
||
|
ReadChar(); // skipping separator
|
||
|
|
||
|
if( !ReadValue() )
|
||
|
return syntax_error;
|
||
|
|
||
|
table.insert( std::make_pair(variable, value) );
|
||
|
}
|
||
|
|
||
|
if( lastc == commentary )
|
||
|
SkipLine();
|
||
|
|
||
|
if( lastc != -1 && lastc != '\n' )
|
||
|
return syntax_error;
|
||
|
|
||
|
ReadChar(); // skipping '\n' if was
|
||
|
}
|
||
|
|
||
|
return ok;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool ConfParser::IsVariableChar(int c)
|
||
|
{
|
||
|
if( (c>='a' && c<='z') ||
|
||
|
(c>='A' && c<='Z') ||
|
||
|
(c>='0' && c<='9') ||
|
||
|
c=='.' || c==',' || c=='_' )
|
||
|
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool ConfParser::IsValueSimpleChar(int c)
|
||
|
{
|
||
|
if( c==-1 || c=='\n' || IsWhite(c) || c==commentary )
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool ConfParser::ReadVariable()
|
||
|
{
|
||
|
variable.clear();
|
||
|
|
||
|
SkipWhite();
|
||
|
|
||
|
while( IsVariableChar(lastc) )
|
||
|
{
|
||
|
variable += lastc;
|
||
|
ReadChar();
|
||
|
}
|
||
|
|
||
|
SkipWhite();
|
||
|
|
||
|
return !variable.empty();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
bool ConfParser::ReadValue()
|
||
|
{
|
||
|
value.clear();
|
||
|
|
||
|
SkipWhite();
|
||
|
|
||
|
|
||
|
if( lastc == '"' )
|
||
|
// quoted value
|
||
|
return ReadValueQuoted();
|
||
|
else
|
||
|
return ReadValueSimple();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
bool ConfParser::ReadValueQuoted()
|
||
|
{
|
||
|
ReadChar(); // skipping the first quote
|
||
|
|
||
|
while( lastc != '\n' && lastc != '"' && lastc != -1 )
|
||
|
{
|
||
|
if( lastc == '\\' )
|
||
|
ReadChar();
|
||
|
|
||
|
value += lastc;
|
||
|
ReadChar();
|
||
|
}
|
||
|
|
||
|
if( lastc != '"' )
|
||
|
return false;
|
||
|
|
||
|
ReadChar(); // skipping the last quote
|
||
|
|
||
|
SkipWhite();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
bool ConfParser::ReadValueSimple()
|
||
|
{
|
||
|
while( IsValueSimpleChar(lastc) )
|
||
|
{
|
||
|
value += lastc;
|
||
|
ReadChar();
|
||
|
}
|
||
|
|
||
|
SkipWhite();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
int ConfParser::ReadChar()
|
||
|
{
|
||
|
lastc = file.get();
|
||
|
|
||
|
if( lastc == '\n' )
|
||
|
++line;
|
||
|
|
||
|
return lastc;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool ConfParser::IsWhite(int c)
|
||
|
{
|
||
|
if( c==' ' || c=='\t' || c==13 )
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void ConfParser::SkipWhite()
|
||
|
{
|
||
|
while( IsWhite(lastc) )
|
||
|
ReadChar();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void ConfParser::SkipLine()
|
||
|
{
|
||
|
while( lastc != -1 && lastc != '\n' )
|
||
|
ReadChar();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|