C90 Support

This commit is contained in:
gingerBill 2016-04-28 15:00:44 +01:00
parent a9462c0843
commit 5e8eeb9157
1 changed files with 70 additions and 73 deletions

143
gb_ini.h
View File

@ -1,43 +1,43 @@
// gb_ini.h - v0.92 - public domain ini file loader library - no warranty implied; use at your own risk /* gb_ini.h - v0.93 - public domain ini file loader library - no warranty implied; use at your own risk
// A Simple Ini File Loader Library for C and C++ A Simple Ini File Loader Library for C and C++
//
// Version History: Version History:
// 0.91 - New styling 0.93 - C90 support
// 0.91a - Error handling fix 0.92 - ??
// 0.91 - Add extern "C" if compiling as C++ 0.91 - New styling
// 0.90 - Initial Version 0.91a - Error handling fix
// 0.91 - Add extern "C" if compiling as C++
// LICENSE 0.90 - Initial Version
//
// This software is in the public domain. Where that dedication is not LICENSE
// recognized, you are granted a perpetual, irrevocable license to copy, This software is in the public domain. Where that dedication is not
// distribute, and modify this file as you see fit. recognized, you are granted a perpetual, irrevocable license to copy,
// distribute, and modify this file as you see fit.
// How to use:
// How to use:
// Do this: Do this:
// #define GB_INI_IMPLEMENTATION #define GB_INI_IMPLEMENTATION
// before you include this file in *one* C++ file to create the implementation before you include this file in *one* C++ file to create the implementation
//
// i.e. it should look like this: i.e. it should look like this:
// #include ... #include ...
// #include ... #include ...
// #include ... #include ...
// #define GB_INI_IMPLEMENTATION #define GB_INI_IMPLEMENTATION
// #include "gb_ini.h" #include "gb_ini.h"
//
// If you prefer to use C++, you can use all the same functions in a If you prefer to use C++, you can use all the same functions in a
// namespace instead, do this: namespace instead, do this:
// #define GB_INI_CPP #define GB_INI_CPP
// before you include the header file before you include the header file
//
// i.e it should look like this: i.e it should look like this:
// #define GB_INI_CPP #define GB_INI_CPP
// #include "gb_ini.h" #include "gb_ini.h"
// */
// Examples:
// /* Examples: */
// test.ini contents /* test.ini contents*/
#if 0 #if 0
; This is a Comment ; This is a Comment
# This is also # This is also
@ -51,15 +51,14 @@ name = Public Domain
[author] [author]
name = Ginger Bill name = Ginger Bill
#endif #endif
// C example /* C example */
#if 0 #if 0
#define GB_INI_IMPLEMENTATION #define GB_INI_IMPLEMENTATION
#include "gb_ini.h" #include "gb_ini.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
struct Library struct Library {
{
char const *name; char const *name;
int version; int version;
char const *license; char const *license;
@ -94,8 +93,7 @@ int main(int argc, char **argv)
{ {
struct Library lib = {0}; struct Library lib = {0};
gbIniError err = gb_ini_parse("test.ini", &test_ini_handler, &lib); gbIniError err = gb_ini_parse("test.ini", &test_ini_handler, &lib);
if (err.type != GB_INI_ERROR_NONE) if (err.type != GB_INI_ERROR_NONE) {
{
if (err.line_num > 0) if (err.line_num > 0)
printf("Line (%d): ", err.line_num); printf("Line (%d): ", err.line_num);
printf("%s\n", gb_ini_error_string(err)); printf("%s\n", gb_ini_error_string(err));
@ -111,8 +109,8 @@ int main(int argc, char **argv)
return 0; return 0;
} }
#endif #endif
//
// C++ example /* C++ example */
#if 0 #if 0
#define GB_INI_CPP #define GB_INI_CPP
#define GB_INI_IMPLEMENTATION #define GB_INI_IMPLEMENTATION
@ -121,8 +119,7 @@ int main(int argc, char **argv)
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
struct Library struct Library {
{
char const *name; char const *name;
int version; int version;
char const *license; char const *license;
@ -160,8 +157,7 @@ int main(int argc, char** argv)
using namespace gb; using namespace gb;
Ini_Error err = ini_parse("test.ini", &test_ini_handler, &lib); Ini_Error err = ini_parse("test.ini", &test_ini_handler, &lib);
if (err.type != INI_ERROR_NONE) if (err.type != INI_ERROR_NONE) {
{
if (err.line_num > 0) if (err.line_num > 0)
printf("Line (%d): ", err.line_num); printf("Line (%d): ", err.line_num);
printf("%s\n", ini_error_string(err)); printf("%s\n", ini_error_string(err));
@ -200,12 +196,12 @@ int main(int argc, char** argv)
#ifndef _MSC_VER #ifndef _MSC_VER
#ifdef __cplusplus #ifdef __cplusplus
#define gb_inline inline #define gbini_inline inline
#else #else
#define gb_inline #define gbini_inline
#endif #endif
#else #else
#define gb_inline __forceinline #define gbini_inline __forceinline
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -222,7 +218,7 @@ enum {
GB_INI_ERROR_ASSIGNMENT_MISSING, GB_INI_ERROR_ASSIGNMENT_MISSING,
GB_INI_ERROR_HANDLER_ERROR, GB_INI_ERROR_HANDLER_ERROR,
GB_INI_ERROR_COUNT, GB_INI_ERROR_COUNT
}; };
typedef struct gbIniError { typedef struct gbIniError {
@ -235,8 +231,9 @@ typedef struct gbIniError {
typedef int gbIniHRT; typedef int gbIniHRT;
#endif #endif
// This macro can be use to declare this type of function without /* This macro can be use to declare this type of function without
// needing to define all the of the parameters * needing to define all the of the parameters
*/
#define GB_INI_HANDLER(func_name) gbIniHRT func_name(void *data, char const *section, char const *name, char const *value) #define GB_INI_HANDLER(func_name) gbIniHRT func_name(void *data, char const *section, char const *name, char const *value)
typedef GB_INI_HANDLER(gbIniHandler); typedef GB_INI_HANDLER(gbIniHandler);
@ -245,7 +242,7 @@ extern char const *GB_ERROR_STRINGS[GB_INI_ERROR_COUNT];
gbIniError gb_ini_parse(char const *filename, gbIniHandler* handler_func, void *data); gbIniError gb_ini_parse(char const *filename, gbIniHandler* handler_func, void *data);
gbIniError gb_ini_parse_file(FILE *file, gbIniHandler* handler_func, void *data); gbIniError gb_ini_parse_file(FILE *file, gbIniHandler* handler_func, void *data);
gb_inline char const *gb_ini_error_string(gbIniError const err) { return GB_ERROR_STRINGS[err.type]; } gbini_inline char const *gb_ini_error_string(gbIniError const err) { return GB_ERROR_STRINGS[err.type]; }
#ifdef __cplusplus #ifdef __cplusplus
} }
@ -261,25 +258,25 @@ namespace gb
typedef gbIniError IniError; typedef gbIniError IniError;
typedef gbIniHandler IniHandler; typedef gbIniHandler IniHandler;
// Just a copy but with the GB_ prefix stripped /* Just a copy but with the GB_ prefix stripped */
enum { enum {
INI_ERROR_NONE = 0, INI_ERROR_NONE = 0,
INI_ERROR_FILE_ERROR, INI_ERROR_FILE_ERROR,
INI_ERROR_MISSING_SECTION_BRACKET, INI_ERROR_MISSING_SECTION_BRACKET,
INI_ERROR_ASSIGNMENT_MISSING, INI_ERROR_ASSIGNMENT_MISSING,
INI_ERROR_HANDLER_ERROR, INI_ERROR_HANDLER_ERROR
// No need for enum count /* No need for enum count */
}; };
inline Ini_Error ini_parse(char const *filename, Ini_Handler *handler_func, void *data) { return gb_ini_parse(filename, handler_func, data); } inline Ini_Error ini_parse(char const *filename, Ini_Handler *handler_func, void *data) { return gb_ini_parse(filename, handler_func, data); }
inline Ini_Error ini_parse(FILE *file, Ini_Handler *handler_func, void *data) { return gb_ini_parse_file(file, handler_func, data); } inline Ini_Error ini_parse(FILE *file, Ini_Handler *handler_func, void *data) { return gb_ini_parse_file(file, handler_func, data); }
inline char const *ini_error_string(const Ini_Error err) { return GB_ERROR_STRINGS[err.type]; } inline char const *ini_error_string(const Ini_Error err) { return GB_ERROR_STRINGS[err.type]; }
} // namespace gb } /* namespace gb */
#endif // GB_INI_CPP #endif /* GB_INI_CPP */
#endif // GB_INI_INCLUDE_GB_INI_H #endif /* GB_INI_INCLUDE_GB_INI_H */
#ifdef GB_INI_IMPLEMENTATION #ifdef GB_INI_IMPLEMENTATION
#include <ctype.h> #include <ctype.h>
@ -294,7 +291,7 @@ char const *GB_ERROR_STRINGS[GB_INI_ERROR_COUNT] = {
"Error in handler function", "Error in handler function",
}; };
static gb_inline char* static gbini_inline char*
gb__left_whitespace_skip(char const *str) gb__left_whitespace_skip(char const *str)
{ {
while (*str && isspace((unsigned char)(*str))) while (*str && isspace((unsigned char)(*str)))
@ -302,7 +299,7 @@ gb__left_whitespace_skip(char const *str)
return (char*)str; return (char*)str;
} }
static gb_inline char* static gbini_inline char*
gb__right_whitespace_strip(char* str) gb__right_whitespace_strip(char* str)
{ {
char* end = str + strlen(str); char* end = str + strlen(str);
@ -311,7 +308,7 @@ gb__right_whitespace_strip(char* str)
return str; return str;
} }
static gb_inline char* static gbini_inline char*
gb__find_char_or_comment_in_string(char const *str, char c) gb__find_char_or_comment_in_string(char const *str, char c)
{ {
int was_whitespace = 0; int was_whitespace = 0;
@ -323,7 +320,7 @@ gb__find_char_or_comment_in_string(char const *str, char c)
return (char*)str; return (char*)str;
} }
static gb_inline char* static gbini_inline char*
gb__string_copy(char* dst, char const *src, size_t size) gb__string_copy(char* dst, char const *src, size_t size)
{ {
strncpy(dst, src, size); strncpy(dst, src, size);
@ -366,7 +363,7 @@ gb_ini_parse_file(FILE *file, gbIniHandler *handler_func, void *data)
start = line; start = line;
#if GB_INI_CHECK_FOR_UTF8_BOM #if GB_INI_CHECK_FOR_UTF8_BOM
// Check for UTF-8 Byte Order Mark /* Check for UTF-8 Byte Order Mark */
if (line_num == 1 && if (line_num == 1 &&
(unsigned char)start[0] == 0xef && (unsigned char)start[0] == 0xef &&
(unsigned char)start[1] == 0xbb && (unsigned char)start[1] == 0xbb &&
@ -378,9 +375,9 @@ gb_ini_parse_file(FILE *file, gbIniHandler *handler_func, void *data)
start = gb__left_whitespace_skip(gb__right_whitespace_strip(start)); start = gb__left_whitespace_skip(gb__right_whitespace_strip(start));
if (start[0] == ';' || start[0] == '#') if (start[0] == ';' || start[0] == '#')
continue; // Allow '#' and ';' comments at start of line continue; /* Allow '#' and ';' comments at start of line */
if (start[0] == '[') { // [section] if (start[0] == '[') { /* [section] */
end = gb__find_char_or_comment_in_string(start+1, ']'); end = gb__find_char_or_comment_in_string(start+1, ']');
if (*end == ']') { if (*end == ']') {
char *sect = start + 1; char *sect = start + 1;
@ -411,7 +408,7 @@ gb_ini_parse_file(FILE *file, gbIniHandler *handler_func, void *data)
err.line_num = line_num; err.line_num = line_num;
} }
} else if (!err.type) { } else if (!err.type) {
// No '=' found on name=value line /* No '=' found on name=value line */
err.type = GB_INI_ERROR_ASSIGNMENT_MISSING; err.type = GB_INI_ERROR_ASSIGNMENT_MISSING;
err.line_num = line_num; err.line_num = line_num;
continue; continue;
@ -425,4 +422,4 @@ gb_ini_parse_file(FILE *file, gbIniHandler *handler_func, void *data)
return err; return err;
} }
#endif // GB_INI_IMPLEMENTATION #endif /* GB_INI_IMPLEMENTATION */