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:
parent
a52c0705c0
commit
5a31af99c4
@ -15,6 +15,27 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#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
|
// 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.)
|
// for simplicity here rather than speed, but it should be pretty decent.)
|
||||||
class INIReader
|
class INIReader
|
||||||
@ -22,45 +43,45 @@ class INIReader
|
|||||||
public:
|
public:
|
||||||
// Construct INIReader and parse given filename. See ini.h for more info
|
// Construct INIReader and parse given filename. See ini.h for more info
|
||||||
// about the parsing.
|
// 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
|
// Construct INIReader and parse given buffer. See ini.h for more info
|
||||||
// about the parsing.
|
// 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
|
// 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.
|
// 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.
|
// 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;
|
const std::string& default_value) const;
|
||||||
|
|
||||||
// Get a string value from INI file, returning default_value if not found,
|
// Get a string value from INI file, returning default_value if not found,
|
||||||
// empty, or contains only whitespace.
|
// 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;
|
const std::string& default_value) const;
|
||||||
|
|
||||||
// Get an integer (long) value from INI file, returning default_value if
|
// 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").
|
// 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
|
// Get a real (floating point double) value from INI file, returning
|
||||||
// default_value if not found or not a valid floating point value
|
// default_value if not found or not a valid floating point value
|
||||||
// according to strtod().
|
// 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
|
// 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",
|
// 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).
|
// 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
|
// Return true if the given section exists (section must contain at least
|
||||||
// one name=value pair).
|
// 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.
|
// 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:
|
private:
|
||||||
int _error;
|
int _error;
|
||||||
|
29
ini.h
29
ini.h
@ -26,6 +26,27 @@ extern "C" {
|
|||||||
#define INI_HANDLER_LINENO 0
|
#define INI_HANDLER_LINENO 0
|
||||||
#endif
|
#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. */
|
/* Typedef for prototype of handler function. */
|
||||||
#if INI_HANDLER_LINENO
|
#if INI_HANDLER_LINENO
|
||||||
typedef int (*ini_handler)(void* user, const char* section,
|
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
|
stop on first error), -1 on file open error, or -2 on memory allocation
|
||||||
error (only when INI_USE_STACK is zero).
|
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
|
/* 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. */
|
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
|
/* 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
|
filename. Used for implementing custom or string-based I/O (see also
|
||||||
ini_parse_string). */
|
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);
|
void* user);
|
||||||
|
|
||||||
/* Same as ini_parse(), but takes a zero-terminated string with the INI data
|
/* 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
|
instead of a file. Useful for parsing INI data from a network socket or
|
||||||
already in memory. */
|
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
|
/* 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
|
configparser. If allowed, ini_parse() will call the handler with the same
|
||||||
|
27
meson.build
27
meson.build
@ -6,6 +6,7 @@ project('inih',
|
|||||||
#### options ####
|
#### options ####
|
||||||
arg_static = []
|
arg_static = []
|
||||||
distro_install = get_option('distro_install')
|
distro_install = get_option('distro_install')
|
||||||
|
extra_args = []
|
||||||
|
|
||||||
if distro_install
|
if distro_install
|
||||||
pkg = import('pkgconfig')
|
pkg = import('pkgconfig')
|
||||||
@ -55,15 +56,26 @@ else
|
|||||||
endif
|
endif
|
||||||
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 ####
|
#### inih ####
|
||||||
inc_inih = include_directories('.')
|
inc_inih = include_directories('.')
|
||||||
|
|
||||||
lib_inih = library('inih',
|
lib_inih = library('inih',
|
||||||
['ini.c'],
|
['ini.c'],
|
||||||
include_directories : inc_inih,
|
include_directories : inc_inih,
|
||||||
c_args : arg_static,
|
c_args : [arg_static, extra_args],
|
||||||
install : distro_install,
|
install : distro_install,
|
||||||
soversion : '0'
|
soversion : '0',
|
||||||
|
gnu_symbol_visibility: 'hidden'
|
||||||
)
|
)
|
||||||
|
|
||||||
if distro_install
|
if distro_install
|
||||||
@ -72,12 +84,13 @@ if distro_install
|
|||||||
pkg.generate(lib_inih,
|
pkg.generate(lib_inih,
|
||||||
name : 'inih',
|
name : 'inih',
|
||||||
description : 'simple .INI file parser',
|
description : 'simple .INI file parser',
|
||||||
|
extra_cflags : extra_args,
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
inih_dep = declare_dependency(
|
inih_dep = declare_dependency(
|
||||||
link_with : lib_inih,
|
link_with : lib_inih,
|
||||||
compile_args : arg_static,
|
compile_args : arg_static + extra_args,
|
||||||
include_directories : inc_inih
|
include_directories : inc_inih
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -88,10 +101,12 @@ if get_option('with_INIReader')
|
|||||||
|
|
||||||
lib_INIReader = library('INIReader',
|
lib_INIReader = library('INIReader',
|
||||||
['cpp/INIReader.cpp'],
|
['cpp/INIReader.cpp'],
|
||||||
|
cpp_args : extra_args,
|
||||||
include_directories : inc_INIReader,
|
include_directories : inc_INIReader,
|
||||||
dependencies : inih_dep,
|
dependencies : inih_dep,
|
||||||
install : distro_install,
|
install : distro_install,
|
||||||
soversion : '0'
|
soversion : '0',
|
||||||
|
gnu_symbol_visibility: 'hidden'
|
||||||
)
|
)
|
||||||
|
|
||||||
if distro_install
|
if distro_install
|
||||||
@ -100,11 +115,13 @@ if get_option('with_INIReader')
|
|||||||
pkg.generate(lib_INIReader,
|
pkg.generate(lib_INIReader,
|
||||||
name : 'INIReader',
|
name : 'INIReader',
|
||||||
description : 'simple .INI file parser for C++',
|
description : 'simple .INI file parser for C++',
|
||||||
|
extra_cflags : extra_args,
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
INIReader_dep = declare_dependency(
|
INIReader_dep = declare_dependency(
|
||||||
link_with : lib_INIReader,
|
link_with : lib_INIReader,
|
||||||
include_directories : inc_INIReader
|
include_directories : inc_INIReader,
|
||||||
|
compile_args : extra_args
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user