#include <strings.h>
#include "iostream"
#include "fstream"
#include <vector>
#include <stack>
Go to the source code of this file.
Classes | |
class | TagInfo |
class | ConfigObj |
class | TypeTagIs |
class | NameIs |
Typedefs | |
typedef vector< TagInfo * > | TagVector |
typedef vector< TagInfo * > ::iterator | TagIterator |
typedef vector< ConfigObj * > | ConfigVector |
typedef vector< ConfigObj * > ::iterator | ConfigIterator |
typedef vector< ConfigObj * > ::reverse_iterator | ConfigRevIterator |
Functions | |
char | ValidateINI (char *filename) |
bool | strToBool (const char *text, bool NoMatch=false) |
This library intended to read text of markup configurations files in uniform way. Text information from the file is loaded by your program in structural tree way. So it facilitates to use text information to supply configuration data to object-oriented software
Advantage - we can use markups to mark groups of the parameters and do not obligued to keep markups for the every Name=Value pairs like XML does. Such text is less dark, less messy, and much more human readable. As opposed to pure XML, and opposed to well known expat library.
The dictionary of markups and their "schemas" are not considered here. Let to deal with names and schemas the classes which will use the data. Markups are caseINSENSITIVE, so big/small letters of the markups does not matter but case sensitivity of Tags -- is also up to your decision. Whitespaces are all removed except those which quoted. Comments marked by #, trailing comments are possible also.
Example of markup configuration text:
# comments are skipped # comment with # in the first column are recognised and skipped faster then others # empty lines just skipped <markup1> # trailing comment, recognised and trimmed slower parameter = value # trailing comment Name = value # syntax of parameters is up to you # we suggest you just the text, cleaned from whitespaces # and structured like a tree # and it is up to your quirk, how to convert it # into member values of your classes and subclass members Tag = "value with whitespaces" # whitespaces are preserved in quotes argument = 'value with whitespaces can be in single quotes also' <incapsulated> parameter = "value with 'single' quote inside " # use "" quote to preserve '' quotes parameter = 'text with "double quote" inside ' # and vice versa IsNotComment = "keeps this # char" # but out of quotes will be trimmed as any trailing comment LikesMilk # boolean, or enum parameters, for example, I think, no need write = true CanEatGrass=false # but nobody can prohibit you to adhere the traditional syntax # just consider the user convinience </incapsulated> Argument = Value SomeParameter = value AuxsillaryConfigFile=/etc/config/read.this.conf # we can include also filenames of other config files # but how to handle this file, is the decision of the your program # you can open them later and handle in the same way as this one </markup1> # end of configuration parameters for this object # the same do for any other object <SomeObject> <SubObject> Leaf=value </SubObject> <SubObject> Leaf=value </SubObject> <SubObject> Leaf = Value Leaf2 = sign Leaf3 = 34 </SubObject> </SomeObject> <IndustrialDevice> Hook= Value Type = "Name of industrial device type" Sensor=UMCTL,3,0x15 <Sensor> # or, such sensor may look better: Board = UMCTL Slot = 3 Address = 0x15 Direction = Input; Name = VacuumOn </Sensor> <AllSensors> /etc/config/sensorfile1 # other config files for sensors /etc/config/sensorfile2 /etc/config/sensorfile683 </AllSensors> </IndustrialDevice>
Well,how to read and use the configuration?
Assume we have configuration file data.conf where all configuration of our application objects is defined.
First we are need just to create the instance of ConfigObj:
ConfigObj Parameters("Root");
res = ValidateINI("data.conf");
if(res==0) Parameters.Load("data.conf");
ConfigIterator Browser; for(Browser = Parameters.ConfigBegin(); Browser < Parameters.ConfigEnd(); Browser++) { if( (*Browser)->IsMyName("IndustrialDevice") ) { TagInfo* TypeTag; if( (TypeTag = (*Browser)->GetParam("Type")) ) { char* Val; Val = strchr(TypeTag->data(),'=')+1; // next after = if(strcasecmp(Val,"fraise")) // we pass the configuration object Fraise->config(*Browser); // to the object instance of our program else if(strcasecmp(Val,"table")) AxisTable->config(*Browser) else if(strcasecmp(Val,"spindle")) Spindle->config(*Browser) else if(strcasecmp(Val,"indexer")) TapeIndexer->config(*Browser) else if(etc...etc...) } } else if( (*Browser)->IsMyName("markup1") ) { MarkupInstance.config(*Browser); } else if(etc...etc...etc...) }
but how to write the member procedure config(ConfigObj* cfg) is the your task, folks
typedef vector<ConfigObj*>::iterator ConfigIterator |
Iterator by collection of the other config objects
typedef vector<ConfigObj*>::reverse_iterator ConfigRevIterator |
typedef vector<ConfigObj*> ConfigVector |
class of vector of pointers to the similar config collections
typedef vector<TagInfo*>::iterator TagIterator |
iterator, is often used to browse Tags
bool strToBool | ( | const char * | text, | |
bool | NoMatch = false | |||
) |
converts some often used strings into booleans
text | the character string to be converted |
char ValidateINI | ( | char * | filename | ) |
checks if file with the given filename can be opened and if all open/close markups are consistent
filename | name of the configuration markup file to be checked |