patterncppMinor
Awesome INI Loader
Viewed 0 times
awesomeloaderini
Problem
I wrote a simple to use C++ INI file parser. The only thing it requires is the STD libs (of course that come with most major C++ compilers) So far it works very well, and the only thing that needs work is the string parser to handle special characters in the key's value. I.E \", \ \n \r.
You can view the code here:
awesome_ini.h
```
#ifndef AWESOME_INI_H
#define AWESOME_INI_H
/*
AUTHOR: Andrew McRobb
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2015 Andrew McRobb
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
*/
#include
#include
#include
#include
#include
#include
//Options you can set...
#define AWI_SEPERATOR_CHAR '='
#define AWI_COMMENT_CHAR ';'
#define AWI_STRING_CHAR '"'
#define AWI_REMOVE_DATA_ON_ERROR true
//Not so awesome error codes...
enum AWESOME_ERROR_CODES
{
AWESOME_ERROR_NONE = 0, /Everything is fine!/
AWESOME_ERROR_FILE_PATH, /The INI specified has an invalid path!/
AWESOME_ERROR_MEMORY, /Rare error code if something happens to break memory limits./
AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS, /The seperator is ether in the wrong location of the line or does not exsist!/
AWESOME_ERROR_PARSING_INVALID_VALUE_TYPE, /The key value type is not reconized./
AWESOME_ERROR_PARSING_LINE_TOO_SHORT, /The line of the file is too short to read. Usually because of invalid syntax./
AWESOME_ERROR_PARSING_INVALID_NAME, /The key or group name has unsupported characters/
AWESOME_ERROR_PARSING_INVALID_LINE, /The line entered usually means another syntax error./
AW
You can view the code here:
awesome_ini.h
```
#ifndef AWESOME_INI_H
#define AWESOME_INI_H
/*
AUTHOR: Andrew McRobb
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2015 Andrew McRobb
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
*/
#include
#include
#include
#include
#include
#include
//Options you can set...
#define AWI_SEPERATOR_CHAR '='
#define AWI_COMMENT_CHAR ';'
#define AWI_STRING_CHAR '"'
#define AWI_REMOVE_DATA_ON_ERROR true
//Not so awesome error codes...
enum AWESOME_ERROR_CODES
{
AWESOME_ERROR_NONE = 0, /Everything is fine!/
AWESOME_ERROR_FILE_PATH, /The INI specified has an invalid path!/
AWESOME_ERROR_MEMORY, /Rare error code if something happens to break memory limits./
AWESOME_ERROR_PARSING_INVALID_SEPERATOR_POS, /The seperator is ether in the wrong location of the line or does not exsist!/
AWESOME_ERROR_PARSING_INVALID_VALUE_TYPE, /The key value type is not reconized./
AWESOME_ERROR_PARSING_LINE_TOO_SHORT, /The line of the file is too short to read. Usually because of invalid syntax./
AWESOME_ERROR_PARSING_INVALID_NAME, /The key or group name has unsupported characters/
AWESOME_ERROR_PARSING_INVALID_LINE, /The line entered usually means another syntax error./
AW
Solution
Here are some points to start with, mostly related to coding style and overall C++ practices (roughly in order of appearance):
-
Careful with your comments, some people might find things like this offensive or inappropriate:
That could drive users away from your project and I would personally never send code with this sort of comments as a portfolio for a job position either.
If you just wish to wave copyrights over the code, this should suffice:
And if you want to get creative, just add a quote from your favorite philosopher at the end.
Edit note: So it turns out that WTFPL is an actual license... Not sure what to make of this... Thanks @FelixBytow for pointing it out.
-
You have nested everything in the header file under the
-
Avoid
-
Consider using the strongly typed
-
Writing
-
-
Consider using a namespace to nest your library, instead of prefixing everything with
-
You have way too many includes exposed in the header file. You don't need
-
By the way, the header files mentioned above are the C headers. In C++ you should be including `
-
Careful with your comments, some people might find things like this offensive or inappropriate:
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSEThat could drive users away from your project and I would personally never send code with this sort of comments as a portfolio for a job position either.
If you just wish to wave copyrights over the code, this should suffice:
// This code is public domain. I claim no copyrights over it.
// No warranty is offered or implied; use it at your own risk.And if you want to get creative, just add a quote from your favorite philosopher at the end.
Edit note: So it turns out that WTFPL is an actual license... Not sure what to make of this... Thanks @FelixBytow for pointing it out.
-
You have nested everything in the header file under the
#ifndef AWESOME_INI_H include guard directive. Don't add that level of indentation. It is not just very unusual, but it also adds nothing to the understanding of the code at the cost of extra horizontal spacing.-
Avoid
#defines for constants. They have no type and provide bad error messages when you use them improperly. What you want for those string constants in the header file is a const char [] or const std::string. Those string constants should also be declared in the .cpp file only, since they are only relevant to the parser internals. Never expose implementation details to the public interface.-
Consider using the strongly typed
enum class if you are targeting C++11.-
Writing
void in the parameter list of a C++ function that takes no parameters (as in getError(void)) is a C-ish style. C++ does not require that; () is just as good. So avoid the unnecessary verbosity.-
virtual destructors are only necessary when your class is meant to be inherited from. In this particular code, that doesn't seem to be the case. If you did that to allow users of your code to inherit from awesome_ini, I would advise against, since Composition is usually much more elegant and with less coupling. You should remove virtual from the destructor declaration and perhaps even mark your class final.-
Consider using a namespace to nest your library, instead of prefixing everything with
awesome_. A namespace awesome { } would be neater.-
You have way too many includes exposed in the header file. You don't need
ctype.h, string.h and stdlib.h in there. Those should go in the implementation (.cpp). This also falls into the category of not exposing implementation details.-
By the way, the header files mentioned above are the C headers. In C++ you should be including `
, and .
-
In most places you are using std::size_t and in a few others just size_t. Make sure you replace those with std::size_t.
-
The constructor of awesome_ini is massive. I suggest breaking it into a few more specific methods to achieve Single Responsibility.
-
Don't use decimal values for character literals (e.g.: c 57 and other places). Use the proper ascii representation ('0' / '9'). std::isdigit() also comes to mind...
-
Which brings use to the next one. Avoid reinventing the wheel. This:
(c == '\n' || c == ' ' || c == '\r' || c == '\t')
Is done by the std::isspace() function from .
-
You have a few methods that take a std::string as parameter and only read from the string (without making copies of it). In such cases, it is better to just take the object by const reference (const std::string & str). Makes it clear that the function only look at the object without copying it. Of course that this is valid for User Defined Types only. Native types such as ints and floats should always be passed by value.
-
The atoi() function is deprecated and has quite a few issues. Prefer std::stoi() (C++11) or std::strtol() otherwise.
-
Since you've named all of your types with snake_case I think it would be nice to keep consistency and also name the methods using this notation. The other way around would also work. PascalCase for types and camelCase` for methods and variables.Code Snippets
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE// This code is public domain. I claim no copyrights over it.
// No warranty is offered or implied; use it at your own risk.(c == '\n' || c == ' ' || c == '\r' || c == '\t')Context
StackExchange Code Review Q#84020, answer score: 6
Revisions (0)
No revisions yet.