One of the better know time-consuming activities for any developer is to provide the users of his programs a way to set up the configuration. Likewise, users can tell you that one of their biggest problems often is to figure out how to configure a given program. Finally, system administrators are often driven to distraction by the fact that a program they'd like to use just cannot be [easily] configured due to security or manageability issues.
As I'm one of the above developers that has to cope with both other groups, I decided to end this issues for once and for all.

The result is a library called AnyConfig. In short what it does is look for the configuration in all the likely places until it finds one that satisfies it's requirements.

Supports having one centralized configuration for all programs you are running. See the included MasterConfig program for a sample application of this.

Configurations can be converted to and from pure string representations, making it possible to specify an entire configuration as a commandline parameter.

Configuration items can be "pointers" to other configuration sources.

Simple access routines are provided (see anycfg.h) and can easily be expanded on.

AnyConfig is Open Source (GPL), you can verify the code and add your own unique configuration method.

Thanks to the new AnyConfig::AcCorbaConfig class you can now use CORBA to access your configuration(s). This in turns means using AnyConfig from Java or other CORBA enabled languages is now possible. It also makes it even easier to centralize your configuration(s).

If all goes well, autoconf should detect which libraries are available on your system and the various modules should comment themselves out if the required support is not available...

Unfortunately, there is no autoconf support for MSDEV/MFC so here you'll probably have to do some manual configuring. Also, including both MFC (for registry access) and Orbacus (for CORBA support) does not work.

If all else fails you should remove the offending modules from either Makefile.am or delete the sub-projects from the MSDEV workspace.

Do let me (Author) know if you're having difficulties and/or ideas for better solutions so I can try to fix it in future versions.

See MasterConfig for a programming example.
Also see the file 'testMe.cpp' for an example of using AnyConfig::AcConfiguration::loadRedundantConfig () which supports fall-back and fail-over type configurations.

Basically all you need to do is to include "AnyConfig.h" in your program (or "anycfg.h" if you are using C instead of C++) and call AcConfiguration::findAnyConfig() (or acfOpen() for plain C).

If there is any kind of configuration lurking around on your system that looks reasonable to AnyConfig, you will obtain an initialized "parent" configuration or even a bootstrapped larger configuration.
Usually you would select the section in this configuration that corresponds to your program and you can obtain (and usually even write back) any configuration items you want.
Lets look at an example. We will assume that you have many programs that use AnyConfig so you have put all of their configurations in a parent configuration file. For each group of programs you have a separate configuration source as well:

It is possible in some cases to indicate a specific configuration source. See AnyConfig::AcConfiguration::loadFrom() for more details.
This is done by supplying a single string in the following format:source:bootstrap:source section:source location
Where:

source

Is one of the supported configuration sources. Currently these are FILE and MYSQL.

bootstrap

Is a boolean indicating that the specified source is only a pointer to the actual source.

As the underlaying configuration sources have different characteristics, keys might be ordered differently. Therefore there are no intrinsic Next/Previous key methods or indeed any other method to iterate through a configuration.
One possible but not recommended work-around is to copy an AnyConfig to an AnyConfig::AcMemConfig, which does support various forms of iteration, using the AnyConfig::AcConfiguration::copyTo() or AnyConfig::AcConfiguration::copyFrom() methods.
The reason this practice is not recommended is that not all configuration sources support the copy methods, for the same reason there is no global iteration facility. Also, this practice might hide changes that were made to the original configuration after the program started, which might not have been your intent.

If you need a sequence in your configuration, like the supplied MasterConfig program for instance, you will have to define your own. Using the CString implementation you will find in the AnyConfig library as well, this can be easily done as follows:

You might wonder how AnyConfig determines the type (Long, Number, Boolean, String) of a configuration item. The answer is simple, it doesn't. Nor is this capability specifically useful.
After all, the program obtaining the configuration defines the type of the configuration item, not the person entering the configuration. If the program expects a Boolean, entering the string "I have no idea" in the configuration does not grant it sudden AI capabilities (AnyConfig would return true for this, by the way, as it is not a number and does not start with either a N or a F).
Nor is it the task of the configuration reading functions to do type checking. Even though the configuration yields a number as expected, the program must still contain code to reject 1E300 or -20000 as being valid percentages...

There are no fixed limits for any of these as again they are mostly defined by the underlaying configuration source.
The default table as created by the AcMySQLConfig class, for instance, limits the names to 40 characters and the value to 255. Copying strings that long to an environment based configuration, however, has a good chance of not working as expected.

You might have noticed that the AnyConfig::AcRegConfig in particular is not very concerned about the length of the section names... About the only target that would accept such long names is the file based configuration class. That one as a limit of 4095 bytes per line, by the way.

AnyConfig is based on the philosophy of allowing as much as possible while doing things as strict as possible itself. In short, any reasonable inputs (and even some debatable ones) are accepted while obvious errors are silently ignored.

A MasterConfigAnyConfig section can contain either a single command line or a compound one with keyword substitution.
Keywords are only substituted if they start with an At sign (@). The whole string is considered to be the keyword to substitute.
This works as follows:

The command line normally has spaces inserted between each CMD_xx part, to avoid this start the argument with @+. You can use @@ if you need an At sign at the beginning of a command line part.
Lines that do not start with an At sign are not parsed so E-mail addresses can be inserted as usual.
Remember that everything after the At sign is considered the keyword.
This will not work:

Building environment strings for a program is rather simular to building a command line.
The main difference is that there is only one commandline but there can be multiple environment strings. Therefore you must start an environment string definition by specifiying the environment key, prefixed with an At sign (@) followed by an Equals sign (=). The following example should clarify this.

On a UN*X system, there is a file in the home directory of the user called '.anycfg.ini'. The MasterConfig will find and load this file automatically.
For this example, we will suppose it has the following content: