diff --git a/cpp/INIReader.h b/cpp/INIReader.h index 9019c35..1571756 100644 --- a/cpp/INIReader.h +++ b/cpp/INIReader.h @@ -15,6 +15,27 @@ #include #include +// 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; diff --git a/ini.h b/ini.h index 78015d1..d1a2ba8 100644 --- a/ini.h +++ b/ini.h @@ -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 diff --git a/meson.build b/meson.build index a4bb4d1..4dc46af 100644 --- a/meson.build +++ b/meson.build @@ -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