Valhalla Legends Forums Archive | C/C++ Programming | [C++] Configuration File Reader

AuthorMessageTime
shadypalm88
I needed a configuration file reader for a server I'm writing that would work on Windows and UNIX-like systems, could organize values into (nested) categroies, and support typed values.  I figured I'd might as well make it generic and reusable.  While not everything is implemented yet, it does read and parse the files and allow applications to get values from them.  Requesting values is easy, for example, if you want the "foo" value in the category "example", just do configObject.get("example/foo").

It's not very sophisticated (no multi-line values, values can't contain { or }, etc), but it does work.  Since this is the first time I've done any parsing, I'd welcome any feedback or comments.  You're of course welcome to use the code in your own projects.

Because of the size of the files, I'll link to them instead of putting them in code tags.  config.h contains the class declaration, config.cpp contains the code, and configtest.cpp is and example program to extract a given value from a config file.

Tested on Mac OS X 10.3 with gcc 3.3 and Windows XP with Microsoft C/C++ Compiler 14.00.40607.16 with UNIX (LF) and Windows (CR/LF) line endlings.

Browse the code (with pretty colors!) [ config.h config.cpp configtest.cpp ]
Example configuration file
Download [ .zip .tar.gz .tar.bz2 ]

Edit: Fixed a typo.
January 2, 2005, 9:33 PM
Myndfyr
Nice work :)
January 5, 2005, 3:03 AM
Mephisto
I don't like how he uses the private access header before the public, and his coding style for that matter.  But all in all, nice work.  :)  I also have a generic file parsing/writing class if anyone would be interested in using/seeing it (I assume it'll compile on all platforms/compilers; there's no Win32 specific code in it).
January 5, 2005, 4:02 AM
Eibro
[quote author=shadypalm88 link=topic=10090.msg94150#msg94150 date=1104701632]
I needed a configuration file reader for a server I'm writing that would work on Windows and UNIX-like systems, could organize values into (nested) categroies, and support typed values.  I figured I'd might as well make it generic and reusable.  While not everything is implemented yet, it does read and parse the files and allow applications to get values from them.  Requesting values is easy, for example, if you want the "foo" value in the category "example", just do configObject.get("example/foo").

It's not very sophisticated (no multi-line values, values can't contain { or }, etc), but it does work.  Since this is the first time I've done any parsing, I'd welcome any feedback or comments.  You're of course welcome to use the code in your own projects.

Because of the size of the files, I'll link to them instead of putting them in code tags.  config.h contains the class declaration, config.cpp contains the code, and configtest.cpp is and example program to extract a given value from a config file.

Tested on Mac OS X 10.3 with gcc 3.3 and Windows XP with Microsoft C/C++ Compiler 14.00.40607.16 with UNIX (LF) and Windows (CR/LF) line endlings.

Browse the code (with pretty colors!) [ config.h config.cpp configtest.cpp ]
Example configuration file
Download [ .zip .tar.gz .tar.bz2 ]

Edit: Fixed a typo.
[/quote]Seems like overkill. It is far easier to implement a solution using the standard library's map/string and the generic algorithms. The conversion to int/bool/whatever really shouldn't be part of the class. Read everything as strings and let the user convert to whatever type they expect to read. A function like this would let the user convert to any desired type:

[code]template <typename T >
T FromString( const std::string& s ) {
    std::stringstream ss;
    ss << s;

    T ret;
    ss >> ret;
    return ret;
}[/code]You could further improve on that by throwing an exception if the conversion fails, or telling stringstream to throw an exception if it fails. Including conversion to different types as member functions of the class binds that code to the class-- you can't use it for anything else but with that class.
January 5, 2005, 4:54 AM
Arta
Eibro's such an STL slut :P
January 5, 2005, 5:41 AM
Mephisto
You should use it, makes your life a lot easier.  :)
January 5, 2005, 5:58 AM
K
This is what I use the boost::program_options library for!
January 5, 2005, 5:00 PM
mynameistmp
I'd take a look at lex/yacc or the more modern flex/bison. You've got a lot of handwritten code for what you're trying to do. Using code generators can reduce the size of your code and will almost certainly reduce the amount of bugs, and thus time spent debugging. Also, the maintainers of your code (if you're working on a commercial level, although it doesn't look like you are judging by your licensing terms) will be more accustomed to the code generated by flex/bison than the code you have written yourself.

Also, why copyright the code then make it open to the public domain, thus surrendering your copyright ?
[quote]
* Copyright (c) 2004-2005 Eric Naeseth
* May be freely used and redistributed.
[/quote]

I'd suggest looking up some free-software licenses. Here's one that might be what you're looking for:
http://www.opensource.org/licenses/mit-license.html
January 6, 2005, 8:43 AM
Arta
[quote author=mynameistmp link=topic=10090.msg94436#msg94436 date=1105001015]
Also, why copyright the code then make it open to the public domain, thus surrendering your copyright ?
[/quote]

Making code public absolutely does not equal surrendering your copyright.
January 6, 2005, 10:04 AM
mynameistmp
Yea, opening the code to the public domain without a license, does. Unless shadypalm88 had:
[quote]
* Copyright (c) 2004-2005 Eric Naeseth
* May be freely used and redistributed.
[/quote]
certified by OSI then he has no rights over the use of the code at all recognizable in a court of law this side of the big pond.
January 6, 2005, 8:42 PM
Myndfyr
[quote author=mynameistmp link=topic=10090.msg94466#msg94466 date=1105044160]
Yea, opening it to the public domain without a license does.
[/quote]

No, it does not.  Writing something original irrevocably grants you a copyright.  Whether you release it with or without a license is of no consequence.  You are entitled to that work whether or not it is in public domain, and at any time you have the right to change whether or not a license is shipped with it.
January 6, 2005, 8:51 PM
mynameistmp
[quote]
Whether you release it with or without a license is of no consequence.
[/quote]

Licenses are important. They can authorize use of code in ways that would be impermissible under copyright law. License terms are designed to protect the copyright. A copyright holder cannot change the terms on a copy you already have. Therefore, in open-source software the copyright holder is almost irrelevant -- but the license terms are very important. He has already released this source, without any certified terms at all, and thus I am free to do whatever I want with it. And yet he has explicitly copyrighted it, so that... what ? He has absolutely no control over how any of us use it. 
January 6, 2005, 9:09 PM
Myndfyr
[quote author=mynameistmp link=topic=10090.msg94468#msg94468 date=1105045779]
Licenses are important. They can authorize use of code in ways that would be impermissible under copyright law. License terms are designed to protect the copyright.
[/quote]
Correct.

[quote author=mynameistmp link=topic=10090.msg94468#msg94468 date=1105045779]
A copyright holder cannot change the terms on a copy you already have.
[/quote]
I don't know why I didn't say that in my first post, but it was implied.  At least in my head.  ;)

[quote author=mynameistmp link=topic=10090.msg94468#msg94468 date=1105045779]
Therefore, in open-source software the copyright holder is almost irrelevant
[/quote]
I disagree.  If you obtained it with regard to a license, you are bound by the license.  If you obtained it directly from the author without any kind of license or contract, I would say you are most likely bound by federal (or the appopriate jurisdiction's) copyright law.  Open-source licenses, such as GNU, are designed to protect the rights of the user as much as the author.  If the author has not granted you these rights in an explicit contract, your posession of it is likely illegal.

[quote author=mynameistmp link=topic=10090.msg94468#msg94468 date=1105045779]
-- but the license terms are very important. He has already released this source, without any certified terms at all, and thus I am free to do whatever I want with it. And yet he has explicitly copyrighted it, so that... what ? He has absolutely no control over how any of us use it. 
[/quote]
If you have it without a license, and it has a registered copyright (as you say, explicit copyright), your posession of it without a license or any other kind of grant-of-use from the author is most likely illegal.  The code that got out of Valve for HL2 constituted copyright infringement.
January 6, 2005, 10:48 PM
shadypalm88
Yes, I'm well aware of open-source licensing.  If this were a full project, I would likely have used an "official" license.  But since I very much doubt that the code I posted would ever be used in a commercial project, I don't much care how it's used.  The only "license" would be
[quote="Me"]May be freely used and redistributed.[/quote]
It is, after all, a programming exercise (that also serves a purpose for me).  Besides, with something this trivial, if I had put the code under a license, and said license had been broken, I wouldn't have bothered to pursue any action against the breaker(s).

Anyway, thanks for all the other feedback as well.  Strings weren't used because the application this reader is for doesn't use strings.  Configuration values are stored using the two primitive types for simplicity in the application (you can always handle conversion from the strings yourself for different types, or subclass / modify the reader).  While I used a map in the application (for associating connection data with socket handles), I felt that considering the categories are nested, it would be better to use custom classes.

While I know about flex, bison, and friends, for something of this (relative) simplicity, and the experience in reading files, I thought that learning how to use those would be overkill.  I also wouldn't want to be linking to an external library (e.g. Boost) just for reading the config.

Anyway, as far as writing the configuration to disk, what do you think would be the best way to handle comments?  Just store them using the line number they're on or adjacent to and try and keep their associations?  Do you regenerate the file from scratch or just try and find/replace, add, and delete values in the original file?
January 7, 2005, 4:23 AM
Arta
[quote author=mynameistmp link=topic=10090.msg94468#msg94468 date=1105045779]
A copyright holder cannot change the terms on a copy you already have.
[/quote]

Wow, are you sure?  That's not the case here (UK).
January 7, 2005, 7:43 AM
mynameistmp
[quote]
Wow, are you sure?  That's not the case here (UK).
[/quote]

Yes.

[quote]
  If you obtained it directly from the author without any kind of license or contract, I would say you are most likely bound by federal (or the appopriate jurisdiction's) copyright law.
[/quote]

You're running in a circle. Copyright law basically constitutes the right to apply licensing terms to the source. Without the licensing terms, there ARE no legal boundaries.

[quote]
If you have it without a license, and it has a registered copyright (as you say, explicit copyright), your posession of it without a license or any other kind of grant-of-use from the author is most likely illegal.
[/quote]

That's an ironic post for this thread. I don't have much else to say on the topic.

January 7, 2005, 8:14 AM
Myndfyr
[quote author=Arta[vL] link=topic=10090.msg94536#msg94536 date=1105083803]
[quote author=mynameistmp link=topic=10090.msg94468#msg94468 date=1105045779]
A copyright holder cannot change the terms on a copy you already have.
[/quote]

Wow, are you sure?  That's not the case here (UK).
[/quote]

It depends.  If the original license says "all rights reserved," "all rights not expressly granted herein are reserved," or "the right to modify this license at any time is reserved," then yes, the copyright owner can change the terms on the copy already owned.

[quote author=mynameistmp link=topic=10090.msg94537#msg94537 date=1105085691]
You're running in a circle. Copyright law basically constitutes the right to apply licensing terms to the source. Without the licensing terms, there ARE no legal boundaries.
[/quote]
No, it depends on how you obtained the original copy of the source code.  If you stole it (for example, by brute-forcing your way into someone's server), then you are infringing on copyright; just because you obtained it without a license from the owner doesn't mean that it doesn't give rights to the owner.  If you obtained it from a place such as PSCode, there is a license that the author agreed to allow his work to be bound by.  If you obtained it just floating about the internet, it is on you to find out the licensing of it.  If Longhorn source code was leaked, any people having it would not have a license and would be in copyright violation, even if you didn't see a license agreement when you were downloading it from the internet.
January 7, 2005, 8:55 AM
R.a.B.B.i.T
*bump*
Sorry for it, but ionws is down, and I can't get a copy of this.  I'm starting more active developement in C++ now, and my efforts at creating any form of config file is horrible (best I've gotten is program crashes on my readini() routine).  Any chance you could upload a copy somewhere else?
July 5, 2005, 4:26 AM
K
[quote author=rabbit link=topic=10090.msg118934#msg118934 date=1120537577]
*bump*
Sorry for it, but ionws is down, and I can't get a copy of this. I'm starting more active developement in C++ now, and my efforts at creating any form of config file is horrible (best I've gotten is program crashes on my readini() routine). Any chance you could upload a copy somewhere else?
[/quote]

I was going to recommend boost::program_options, but I see I already did about 6 months ago ;)
July 5, 2005, 5:22 AM
R.a.B.B.i.T
Eh?  I don't remember any recommendations :X

From what I've read about boost it's for command lines, but that's not what I'm looking for :\
July 5, 2005, 11:32 PM
K
[quote author=rabbit link=topic=10090.msg119108#msg119108 date=1120606341]
Eh? I don't remember any recommendations :X

From what I've read about boost it's for command lines, but that's not what I'm looking for :\
[/quote]

Actually, boost is for a ton of different things -- boost::program_options however supports several different methods of reading program options, one of which happens to be the command line.  However it also supports reading configuration files.

Here's a little snippet:
[code]
//
namespace po = boost::program_options;
std::string user_name;
std::string user_password;
std::string remote_host;
unsigned short remote_port;
// etc..


// ...

std::ifstream in_file(config_file.c_str());

po::options_description config("Configuration");
config.add_options()
("User-Name", po::value<std::string>(&user_name)->default_value("anonymous"), "Your battle.net user name.")
("User-Password", po::value<std::string>(&user_password)->default_value(""), "Your battle.net password.")
("Remote-Server", po::value<std::string>(&remote_server)->default_value("useast.battle.net"), "Server's hostname or IP address.")
("Remote-Port", po::value<unsigned short>(&remote_port)->default_value(6112), "Server's port.");


try
{
po::variables_map vm;
po::store(po::parse_config_file(in_file, config), vm);
po::notify(vm);
}
catch(std::exception& ex)
{
std::cerr << config << std::endl;
std::cerr << ex.what() << std::endl;
return false;
}

in_file.close();
[/code]
July 6, 2005, 12:42 AM
R.a.B.B.i.T
Well I missed that...I'll look more closely.
July 6, 2005, 3:36 AM

Search