====== xini (ini/configuration file handling class) ======
===== Motivation =====
Storing configuration settings in .MAT-files makes it sometimes more cumbersome to change those settings (particularly when trying to compare a prior set to the currently used one). In such cases, it can be helpful to store the settings in a text file.
However, as Matlab does not have builtin support for storing multiple variables in structured textfiles, I decided to implement a class that would handle such files. The class has the following main features:
* reading/writing ini-files (see below for format description)
* accessing "sections" and individual settings within the object
* grandfathering settings (or sections) from another object
===== Requirements =====
The [[any2ascii]] function must be properly working (e.g. if user-defined classes are used, it must be overloaded).
===== Reference ('help xini') =====
xini (class)
creates an object for ini-file handling
Input: for meaningful object construction, give filename!
___ Constructor methods: ___
----------------------------
xini returns a handle to an xini object
FORMAT: IniFileObject = xini(Filename [,convert]);
FORMAT: NewObject = xini('convert' | 'new');
FORMAT: FactoryObject = xini;
ReleaseAllFiles issue release for all open objects
ReloadAllFiles issue reload for all open objects
ResetClass resets the internal variable, useful for debugging
SetIniString create an IniFile object from an inistring
___ NOTES: ___
--------------
*) with conversion active, xini uses any2ascii, another part
of this toolbox to write non-character variables to disk;
when not active, only valid one-line char arrays are allowed!
**) storage for the ini file settings is NOT part of the object, but
is requested and maintained by the singleton object itself, thus
only little memory is needed for argument handling, even with
bigger ini file, plus multiple functions can share one ini file!
===== ini file format =====
Information in these ini files is stored as follows
* a free-text header of variable length can be stored (any text prior to the first occurrence of the ''['' character at the beginning of a line)
* a free-text footer of variable length can be stored (any text following the line that reads ''[/EndOfXINI]'')
* information is grouped into "sections" (internally represented by one struct per section) and, possibly, sub-sections (structs as the field of the section struct)
* individual settings are stored as numbers, with support for cell arrays and logical values
As an example, here is the ''Statistics'' section from the ''neuroelf.ini'' file in the ''_core/config'' sub-folder of NeuroElf (see [[NeuroElf installation#installation_folder_structure|folder structure]] of NeuroElf):
[Statistics]
ClusterTableAdd=[false]
ExtractOnSelect=[true]
InterpMethod=linear
JoinMaps=[true]
LocalMax=[true]
LocalMaxSrfNeigh=[4]
LookupCoord=peak
RobustVOICondAvg=[false]
ShowThreshBars=[true]
ThreshBarPos=[0.93,0.25,0.99,0.75]
Thresholds=[0.05,0.02,0.01,0.005,0.002,0.001,0.0005,0.0001,5e-05,1e-05,5e-06,1e-06]
As you can see, both text-based tokens (''InterpMethod'' and ''LookupCoord'' setting) as well as numeric (e.g. ''Thresholds'') and boolean (e.g. ''ShowThreshBars'') values can be stored.
===== ini object access =====
To access the contents of an object, the filename is passed into the xini constructor:
% read the neuroelf config file with support for numeric/complex values
neuroelf_ini = xini([neuroelf_path '/_core/config/neuroelf.ini'], 'convert');
Sections and settings can then be accessed with the overloaded [[@xini/subsref]] and [[xini/subsasgn]] functions:
% add another threshold
neuroelf_ini.Statistics.Thresholds(end+1) = 0.1 * neuroelf_ini.Statistics.Thresholds(end);
And to write a file back to disk, the [[xini.Save]] method can be used:
% save the object back to disk
neuroelf_ini.Save;