• Welcome to Valhalla Legends Archive.
 

[C++] Configuration File Reader

Started by shadypalm88, January 02, 2005, 03:33 PM

Previous topic - Next topic

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.

MyndFyre

QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

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).

Eibro

Quote from: shadypalm88 on January 02, 2005, 03:33 PM
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.
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:

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

     T ret;
     ss >> ret;
     return ret;
}
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.
Eibro of Yeti Lovers.

Arta


Mephisto

You should use it, makes your life a lot easier.  :)

K


mynameistmp

#7
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.

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
"This idea is so odd, it is hard to know where to begin in challenging it." - Martin Barker, British scholar

Arta

Quote from: mynameistmp on January 06, 2005, 02:43 AM
Also, why copyright the code then make it open to the public domain, thus surrendering your copyright ?

Making code public absolutely does not equal surrendering your copyright.

mynameistmp

#9
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.
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.
"This idea is so odd, it is hard to know where to begin in challenging it." - Martin Barker, British scholar

MyndFyre

Quote from: mynameistmp on January 06, 2005, 02:42 PM
Yea, opening it to the public domain without a license does.

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.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

mynameistmp

Quote
Whether you release it with or without a license is of no consequence.

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. 
"This idea is so odd, it is hard to know where to begin in challenging it." - Martin Barker, British scholar

MyndFyre

Quote from: mynameistmp on January 06, 2005, 03:09 PM
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.
Correct.

Quote from: mynameistmp on January 06, 2005, 03:09 PM
A copyright holder cannot change the terms on a copy you already have.
I don't know why I didn't say that in my first post, but it was implied.  At least in my head.  ;)

Quote from: mynameistmp on January 06, 2005, 03:09 PM
Therefore, in open-source software the copyright holder is almost irrelevant
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 from: mynameistmp on January 06, 2005, 03:09 PM
-- 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. 
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.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

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 from: MeMay be freely used and redistributed.
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?

Arta

Quote from: mynameistmp on January 06, 2005, 03:09 PM
A copyright holder cannot change the terms on a copy you already have.

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