ConfigML |
Configuration Markup Language |
|||
|
This library intended to read configurations text files. Text information from the file is slurped by ConfigObj class instance as a tree of config groups and name=value text pairs. After that we can supply the subtrees of configuration parameters to corresponding class instances in your program
And you should write the configuration method procedure for your class, which then browses through given parameter tree and assigns class instance member values accordingly. Advantage - we can use markups to mark groups of the parameters and do obligued not to keep markups for the every Name=Value pairs like XML does. Such text is less messy, and much more human readable then XML. The dictionary of markups and their "schemas" are not considered here. Let the classes to deal with names and schemas 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? ConfigObj Parameters("Root"); res = ValidateINI("data.conf"); if(res==0) Parameters.Load("data.conf"); then we can iterate Configuration objects and pass them to member functions of class instances to be configured, just after they were created in memory
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 Additional information about files and classes of you can read in Doxy files |