2008-12-11 03:46:16 +01:00
|
|
|
/*
|
2010-02-28 01:08:10 +01:00
|
|
|
* This file is a part of Winix
|
2008-12-11 03:46:16 +01:00
|
|
|
* and is not publicly distributed
|
|
|
|
*
|
2010-02-28 22:33:06 +01:00
|
|
|
* Copyright (c) 2008-2010, Tomasz Sowa
|
2008-12-11 03:46:16 +01:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef headerfileconfparser
|
|
|
|
#define headerfileconfparser
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
#include <string>
|
2010-07-21 19:24:16 +02:00
|
|
|
#include <vector>
|
2008-12-11 03:46:16 +01:00
|
|
|
#include <map>
|
|
|
|
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
A parser for parsing config files.
|
|
|
|
|
|
|
|
A config file can look like this:
|
|
|
|
variable1 = value 1
|
|
|
|
variable2 = " value 2 "
|
|
|
|
variable3 = (value 1, value 2)
|
|
|
|
variable4 = (" value 1 " , "value2", value 3)
|
|
|
|
|
|
|
|
sample of use:
|
|
|
|
ConfParser parser;
|
|
|
|
parser.Parse("/path/to/config");
|
|
|
|
|
|
|
|
if( parser.status == ConfParser::ok )
|
|
|
|
{
|
|
|
|
// the whole config we have in parser.table (parser.table_single)
|
|
|
|
}
|
|
|
|
|
|
|
|
config syntax:
|
|
|
|
option = list
|
|
|
|
|
|
|
|
list can consists of any number of items, if you're using more than one item you should
|
|
|
|
use brackets ()
|
|
|
|
|
|
|
|
for one item the brackets can be ommited:
|
|
|
|
option = value
|
|
|
|
white characters at the beginning of the value (and at the end) will be trimmed,
|
|
|
|
or you can use quotes:
|
|
|
|
option = "value"
|
|
|
|
option2 = "value with spaces at the end "
|
|
|
|
|
|
|
|
the form without quotes:
|
|
|
|
option = value
|
|
|
|
should be written in one line, so this is not allowed:
|
|
|
|
option =
|
|
|
|
value
|
|
|
|
you can use a new line characters only between brackets and quotes:
|
|
|
|
option = "this is
|
|
|
|
a multiline string"
|
|
|
|
option = ( value1,
|
|
|
|
value2 )
|
|
|
|
|
|
|
|
but there is one requirement: the first character " or ( should be in the same line,
|
|
|
|
so this is not allowed
|
|
|
|
option =
|
|
|
|
"this is wrong"
|
|
|
|
but this is ok:
|
|
|
|
option = "
|
|
|
|
that is ok"
|
|
|
|
|
|
|
|
empty lists:
|
|
|
|
option = ()
|
|
|
|
this creates an empty list: parser.table['option'].empty() == true
|
|
|
|
|
|
|
|
option =
|
|
|
|
this creates an empty list too (the same as previously)
|
|
|
|
|
|
|
|
option = ""
|
|
|
|
but this doesn't create an empty list, it creates a list with one (empty) item
|
|
|
|
|
|
|
|
commentaries:
|
|
|
|
# this is a commentary (until the end of the line)
|
|
|
|
option = value # this is a commentary too
|
|
|
|
|
|
|
|
commentaries are treated as white characters, other example:
|
|
|
|
option = ( # this is my list
|
|
|
|
"value 1" # this is a value one
|
|
|
|
value 2 # and this is a value two
|
|
|
|
) # end of my list
|
|
|
|
|
|
|
|
overwriting:
|
|
|
|
option1 = some value
|
|
|
|
option1 = other value
|
|
|
|
# always the last option is used so option1 is "other value"
|
|
|
|
|
|
|
|
list delimiter:
|
|
|
|
option1 = (value1, value2, value3)
|
|
|
|
option2 = ("value1", "value2", "value3")
|
|
|
|
above we're using a comma ',' as a list delimiter but when using quotes (second line)
|
|
|
|
the commas can be omitted:
|
|
|
|
option2 = ("value1" "value2" "value3")
|
|
|
|
|
|
|
|
white characters:
|
|
|
|
the name of an option cannot consist of white characters
|
|
|
|
some option = value # this is wrong
|
|
|
|
some_option = value # this is ok
|
|
|
|
|
|
|
|
which characters are allowed in an option name is defined by IsVariableChar() method
|
|
|
|
|
|
|
|
you can use white characters in values
|
|
|
|
option = value with spaces or tabs
|
|
|
|
white characters at the beginning and at the end will be trimmed,
|
|
|
|
so if you want them use quotes:
|
|
|
|
option = " other value with spaces "
|
|
|
|
|
|
|
|
special characters in quoted strings:
|
|
|
|
option = "this is a string with \" a quote inside"
|
|
|
|
the option will be: this is a string with " a quote inside
|
|
|
|
\\ - means one \
|
|
|
|
basically: \char produces char
|
|
|
|
so:
|
|
|
|
"\a" gives "a"
|
|
|
|
"\\" gives "\"
|
|
|
|
"\Z" gives "Z" and so on
|
2010-08-16 16:15:37 +02:00
|
|
|
you can call UseEscapeChar(false) to turn this off
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
*/
|
2008-12-11 03:46:16 +01:00
|
|
|
class ConfParser
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
ConfParser();
|
|
|
|
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
/*
|
|
|
|
status of parsing
|
|
|
|
*/
|
|
|
|
enum Status { ok, cant_open_file, syntax_error };
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
the last status of parsing, set by Parse() methods
|
|
|
|
*/
|
2008-12-11 03:46:16 +01:00
|
|
|
Status status;
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
the main methods used to parse
|
|
|
|
file_name is the path to a file
|
|
|
|
*/
|
|
|
|
Status Parse(const char * file_name);
|
|
|
|
Status Parse(const std::string & file_name);
|
|
|
|
|
2008-12-11 03:46:16 +01:00
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
/*
|
|
|
|
a number of a line in which there is a syntax_error
|
|
|
|
*/
|
2008-12-11 03:46:16 +01:00
|
|
|
int line;
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
this is the table which represents your config file
|
|
|
|
in the Table map: the first (key) is your 'option' and the second is 'list'
|
|
|
|
*/
|
|
|
|
typedef std::vector<std::string> Value;
|
|
|
|
typedef std::map<std::string, Value> Table;
|
2008-12-11 03:46:16 +01:00
|
|
|
Table table;
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
if your config file consists mainly of single forms such as:
|
|
|
|
option = value
|
|
|
|
option2 = value2
|
|
|
|
then you can call SplitSingle(true) for not inserting single values to
|
|
|
|
previous 'table' but instead to 'table_single'
|
|
|
|
table_single as the second parameter takes only std::string (instead of the whole std::vector)
|
|
|
|
so you can save a little memory from not using std::vector
|
|
|
|
*/
|
|
|
|
typedef std::map<std::string, std::string> TableSingle;
|
|
|
|
TableSingle table_single;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
if your list consists of only one item, e.g:
|
|
|
|
option1 = value 1
|
|
|
|
option2 = "value 2"
|
|
|
|
option3 = ( "value 3" )
|
|
|
|
then if you call SplitSingle(true) then such values will be stored in
|
|
|
|
'table_single' instead of 'table' map
|
|
|
|
default: false
|
|
|
|
*/
|
|
|
|
void SplitSingle(bool split);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
if true then empty lists, e.g:
|
|
|
|
option =
|
|
|
|
option2 = ()
|
|
|
|
will be omitted (not inserted to 'table' or 'table_single')
|
|
|
|
default: false
|
|
|
|
*/
|
|
|
|
void SkipEmpty(bool skip);
|
|
|
|
|
|
|
|
|
2010-08-16 16:15:37 +02:00
|
|
|
/*
|
|
|
|
'\' character is used to escape other characters in a quoted string
|
|
|
|
so "some \t t\"ext" will produce "some t t"ext"
|
|
|
|
(this is only use in quoted string)
|
|
|
|
default: true
|
|
|
|
*/
|
|
|
|
void UseEscapeChar(bool escape);
|
|
|
|
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
/*
|
|
|
|
those methods are used to extract information from table or table_single
|
|
|
|
as a parameter they take the name of an option
|
|
|
|
and a default value (if there is no such a parameter),
|
|
|
|
they return appropriate value (either text, int or boolean)
|
|
|
|
(in lists they return the first item if exists)
|
|
|
|
*/
|
|
|
|
std::string Text(const char * name);
|
|
|
|
std::string Text(const char * name, const char * def);
|
|
|
|
std::string Text(const std::string & name, const std::string & def);
|
|
|
|
int Int(const char *);
|
|
|
|
int Int(const char * name, int def);
|
|
|
|
int Int(const std::string & name, int def);
|
2010-08-12 21:10:12 +02:00
|
|
|
size_t Size(const char *);
|
|
|
|
size_t Size(const char * name, size_t def);
|
|
|
|
size_t Size(const std::string & name, size_t def);
|
2010-08-10 18:12:50 +02:00
|
|
|
bool Bool(const char *);
|
|
|
|
bool Bool(const char * name, bool def);
|
|
|
|
bool Bool(const std::string & name, bool def);
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
|
2010-08-10 18:12:50 +02:00
|
|
|
/*
|
|
|
|
some default values
|
|
|
|
used in Text() Int() or Bool() when you don't explicitly set the default value
|
|
|
|
|
|
|
|
if you don't set it directly then:
|
|
|
|
default text is: "" (empty)
|
2010-08-12 21:10:12 +02:00
|
|
|
default int or size is: 0
|
2010-08-10 18:12:50 +02:00
|
|
|
default bool is: false
|
|
|
|
*/
|
|
|
|
void SetDefaultText(const std::string & def);
|
|
|
|
void SetDefaultInt(int def);
|
2010-08-12 21:10:12 +02:00
|
|
|
void SetDefaultSize(size_t def);
|
2010-08-10 18:12:50 +02:00
|
|
|
void SetDefaultBool(bool def);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
those methods are used to extract lists
|
|
|
|
note: if there is one option in table_single they will return it
|
|
|
|
*/
|
|
|
|
void ListText(const char * name, std::vector<std::string> & list);
|
|
|
|
void ListText(const std::string & name, std::vector<std::string> & list);
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
|
2008-12-11 03:46:16 +01:00
|
|
|
private:
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
/*
|
|
|
|
last read variable (option)
|
|
|
|
*/
|
|
|
|
std::string variable;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
last read list item
|
|
|
|
*/
|
|
|
|
std::string value_item;
|
2008-12-11 03:46:16 +01:00
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
last read list
|
|
|
|
*/
|
|
|
|
Value value;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
separator between a variable and a value, default: '='
|
|
|
|
*/
|
2008-12-11 03:46:16 +01:00
|
|
|
int separator;
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
commentary char, default: '#'
|
|
|
|
*/
|
2008-12-11 03:46:16 +01:00
|
|
|
int commentary;
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
list starting character, default: '('
|
|
|
|
*/
|
|
|
|
int list_start;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
list ending character, default: ')'
|
|
|
|
*/
|
|
|
|
int list_end;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
list delimiter, default: ','
|
|
|
|
*/
|
|
|
|
int list_delimiter;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
last read char
|
|
|
|
*/
|
2008-12-11 03:46:16 +01:00
|
|
|
int lastc;
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
current file
|
|
|
|
*/
|
2008-12-11 03:46:16 +01:00
|
|
|
std::ifstream file;
|
|
|
|
|
|
|
|
|
2010-07-21 19:24:16 +02:00
|
|
|
/*
|
|
|
|
if true then lists with one item will be put into 'table_single' table
|
|
|
|
default: false
|
|
|
|
*/
|
|
|
|
bool split_single;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
if true then empty lists, e.g:
|
|
|
|
option =
|
|
|
|
option2 = ()
|
|
|
|
will be omitted (not inserted to 'table' or 'table_single')
|
|
|
|
default: false
|
|
|
|
*/
|
|
|
|
bool skip_empty;
|
|
|
|
|
|
|
|
|
2010-08-16 16:15:37 +02:00
|
|
|
/*
|
|
|
|
if true you can use an escape character '\' in quoted values
|
|
|
|
*/
|
|
|
|
bool use_escape_char;
|
2010-08-10 18:12:50 +02:00
|
|
|
|
|
|
|
std::string default_str;
|
|
|
|
int default_int;
|
2010-08-12 21:10:12 +02:00
|
|
|
size_t default_size;
|
2010-08-10 18:12:50 +02:00
|
|
|
bool default_bool;
|
|
|
|
|
|
|
|
int ToInt(const std::string & value);
|
2010-08-12 21:10:12 +02:00
|
|
|
size_t ToSize(const std::string & value);
|
2010-08-10 18:12:50 +02:00
|
|
|
bool ToBool(const std::string & value);
|
|
|
|
|
2008-12-11 03:46:16 +01:00
|
|
|
Status ParseFile();
|
2010-07-21 19:24:16 +02:00
|
|
|
void AddOption();
|
|
|
|
|
|
|
|
void DeleteFromTable(const std::string & var);
|
|
|
|
void DeleteFromTableSingle(const std::string & var);
|
2008-12-11 03:46:16 +01:00
|
|
|
|
|
|
|
bool ReadVariable();
|
|
|
|
bool ReadValue();
|
2010-07-21 19:24:16 +02:00
|
|
|
bool ReadValueList();
|
|
|
|
bool ReadValueNoList(bool use_list_delimiter = false);
|
2008-12-11 03:46:16 +01:00
|
|
|
bool ReadValueQuoted();
|
2010-07-21 19:24:16 +02:00
|
|
|
bool ReadValueSimple(bool use_list_delimiter = false);
|
2008-12-11 03:46:16 +01:00
|
|
|
|
|
|
|
int ReadChar();
|
|
|
|
bool IsWhite(int c);
|
2010-07-21 19:24:16 +02:00
|
|
|
bool IsVariableChar(int c);
|
2008-12-11 03:46:16 +01:00
|
|
|
void SkipWhite();
|
2010-07-21 19:24:16 +02:00
|
|
|
void SkipWhiteLines();
|
2008-12-11 03:46:16 +01:00
|
|
|
void SkipLine();
|
2010-01-28 16:39:01 +01:00
|
|
|
void Trim(std::string & s);
|
2008-12-11 03:46:16 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|