1
0
mirror of https://github.com/benhoyt/inih.git synced 2025-01-28 22:52:54 +08:00

Add visibility symbols (#134)

They are required to properly build DLLs on Windows, and improve the
quality of shared objects on Linux.
See https://gcc.gnu.org/wiki/Visibility for details.

This issue was first discovered here:
https://github.com/mesonbuild/wrapdb/pull/340#issuecomment-1075102565
This commit is contained in:
Andrea Pappacoda 2022-03-23 20:30:27 +01:00 committed by GitHub
parent a52c0705c0
commit 5a31af99c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 78 additions and 19 deletions

View File

@ -15,6 +15,27 @@
#include <map>
#include <string>
// Visibility symbols, required for Windows DLLs
#ifndef INI_API
#if defined _WIN32 || defined __CYGWIN__
# ifdef INI_SHARED_LIB
# ifdef INI_SHARED_LIB_BUILDING
# define INI_API __declspec(dllexport)
# else
# define INI_API __declspec(dllimport)
# endif
# else
# define INI_API
# endif
#else
# if defined(__GNUC__) && __GNUC__ >= 4
# define INI_API __attribute__ ((visibility ("default")))
# else
# define INI_API
# endif
#endif
#endif
// Read an INI file into easy-to-access name/value pairs. (Note that I've gone
// for simplicity here rather than speed, but it should be pretty decent.)
class INIReader
@ -22,45 +43,45 @@ class INIReader
public:
// Construct INIReader and parse given filename. See ini.h for more info
// about the parsing.
explicit INIReader(const std::string& filename);
INI_API explicit INIReader(const std::string& filename);
// Construct INIReader and parse given buffer. See ini.h for more info
// about the parsing.
explicit INIReader(const char *buffer, size_t buffer_size);
INI_API explicit INIReader(const char *buffer, size_t buffer_size);
// Return the result of ini_parse(), i.e., 0 on success, line number of
// first error on parse error, or -1 on file open error.
int ParseError() const;
INI_API int ParseError() const;
// Get a string value from INI file, returning default_value if not found.
std::string Get(const std::string& section, const std::string& name,
INI_API std::string Get(const std::string& section, const std::string& name,
const std::string& default_value) const;
// Get a string value from INI file, returning default_value if not found,
// empty, or contains only whitespace.
std::string GetString(const std::string& section, const std::string& name,
INI_API std::string GetString(const std::string& section, const std::string& name,
const std::string& default_value) const;
// Get an integer (long) value from INI file, returning default_value if
// not found or not a valid integer (decimal "1234", "-1234", or hex "0x4d2").
long GetInteger(const std::string& section, const std::string& name, long default_value) const;
INI_API long GetInteger(const std::string& section, const std::string& name, long default_value) const;
// Get a real (floating point double) value from INI file, returning
// default_value if not found or not a valid floating point value
// according to strtod().
double GetReal(const std::string& section, const std::string& name, double default_value) const;
INI_API double GetReal(const std::string& section, const std::string& name, double default_value) const;
// Get a boolean value from INI file, returning default_value if not found or if
// not a valid true/false value. Valid true values are "true", "yes", "on", "1",
// and valid false values are "false", "no", "off", "0" (not case sensitive).
bool GetBoolean(const std::string& section, const std::string& name, bool default_value) const;
INI_API bool GetBoolean(const std::string& section, const std::string& name, bool default_value) const;
// Return true if the given section exists (section must contain at least
// one name=value pair).
bool HasSection(const std::string& section) const;
INI_API bool HasSection(const std::string& section) const;
// Return true if a value exists with the given section and field names.
bool HasValue(const std::string& section, const std::string& name) const;
INI_API bool HasValue(const std::string& section, const std::string& name) const;
private:
int _error;

29
ini.h
View File

@ -26,6 +26,27 @@ extern "C" {
#define INI_HANDLER_LINENO 0
#endif
/* Visibility symbols, required for Windows DLLs */
#ifndef INI_API
#if defined _WIN32 || defined __CYGWIN__
# ifdef INI_SHARED_LIB
# ifdef INI_SHARED_LIB_BUILDING
# define INI_API __declspec(dllexport)
# else
# define INI_API __declspec(dllimport)
# endif
# else
# define INI_API
# endif
#else
# if defined(__GNUC__) && __GNUC__ >= 4
# define INI_API __attribute__ ((visibility ("default")))
# else
# define INI_API
# endif
#endif
#endif
/* Typedef for prototype of handler function. */
#if INI_HANDLER_LINENO
typedef int (*ini_handler)(void* user, const char* section,
@ -52,22 +73,22 @@ typedef char* (*ini_reader)(char* str, int num, void* stream);
stop on first error), -1 on file open error, or -2 on memory allocation
error (only when INI_USE_STACK is zero).
*/
int ini_parse(const char* filename, ini_handler handler, void* user);
INI_API int ini_parse(const char* filename, ini_handler handler, void* user);
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
close the file when it's finished -- the caller must do that. */
int ini_parse_file(FILE* file, ini_handler handler, void* user);
INI_API int ini_parse_file(FILE* file, ini_handler handler, void* user);
/* Same as ini_parse(), but takes an ini_reader function pointer instead of
filename. Used for implementing custom or string-based I/O (see also
ini_parse_string). */
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
INI_API int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
void* user);
/* Same as ini_parse(), but takes a zero-terminated string with the INI data
instead of a file. Useful for parsing INI data from a network socket or
already in memory. */
int ini_parse_string(const char* string, ini_handler handler, void* user);
INI_API int ini_parse_string(const char* string, ini_handler handler, void* user);
/* Nonzero to allow multi-line value parsing, in the style of Python's
configparser. If allowed, ini_parse() will call the handler with the same

View File

@ -6,6 +6,7 @@ project('inih',
#### options ####
arg_static = []
distro_install = get_option('distro_install')
extra_args = []
if distro_install
pkg = import('pkgconfig')
@ -55,15 +56,26 @@ else
endif
endif
if host_machine.system() == 'windows'
lib = get_option('default_library')
if lib == 'both'
error('default_library=both is not supported on Windows')
elif lib == 'shared'
extra_args += '-DINI_SHARED_LIB'
add_project_arguments('-DINI_SHARED_LIB_BUILDING', language: ['c', 'cpp'])
endif
endif
#### inih ####
inc_inih = include_directories('.')
lib_inih = library('inih',
['ini.c'],
include_directories : inc_inih,
c_args : arg_static,
c_args : [arg_static, extra_args],
install : distro_install,
soversion : '0'
soversion : '0',
gnu_symbol_visibility: 'hidden'
)
if distro_install
@ -72,12 +84,13 @@ if distro_install
pkg.generate(lib_inih,
name : 'inih',
description : 'simple .INI file parser',
extra_cflags : extra_args,
)
endif
inih_dep = declare_dependency(
link_with : lib_inih,
compile_args : arg_static,
compile_args : arg_static + extra_args,
include_directories : inc_inih
)
@ -88,10 +101,12 @@ if get_option('with_INIReader')
lib_INIReader = library('INIReader',
['cpp/INIReader.cpp'],
cpp_args : extra_args,
include_directories : inc_INIReader,
dependencies : inih_dep,
install : distro_install,
soversion : '0'
soversion : '0',
gnu_symbol_visibility: 'hidden'
)
if distro_install
@ -100,11 +115,13 @@ if get_option('with_INIReader')
pkg.generate(lib_INIReader,
name : 'INIReader',
description : 'simple .INI file parser for C++',
extra_cflags : extra_args,
)
endif
INIReader_dep = declare_dependency(
link_with : lib_INIReader,
include_directories : inc_INIReader
include_directories : inc_INIReader,
compile_args : extra_args
)
endif