Moar porting.

This commit is contained in:
Alexander Shaduri
2018-01-01 00:29:24 +00:00
parent 72343e1067
commit c77d23be7a
24 changed files with 59 additions and 895 deletions
+4 -7
View File
@@ -32,6 +32,7 @@ Don't rely on smartctl return code (2), parse the output instead.
GTKMM 4.
app_pango_strip_markup to pangomm (seems to be in the latest version, but not in the shipped one).
scoped_ptr (after we have GtkFileChooserNative in gtkmm)
GTK_CHECK_VERSION, GTK_CHECK_VERSION
JSON.
Port the rest to std::regex, get rid of pcre requirement.
@@ -42,17 +43,13 @@ string_num (may require locale set to C).
type_properties.h / type_categories.h (after ascii.h and string_num.h)
Port to std::filesystem (gcc 8; mingw not yet supported).
wcmatch (once fs is gone)
remove wcmatch (once fs is gone)
remove i18n.h
scoped_array
std::wstring in mingw instead of wchar_t?
format_date() -> C++17 has it.
snprintf
format_date(), format_time_length -> C++17 has it.
some string_algo
string_sprintf?
Check licenses - do we still use boost, bsd?
std::string setters -> no const&, use std::move.
local_algo (after hz::fs)
enum class
static std::map
@@ -1,51 +0,0 @@
############################################################################
# Copyright:
# (C) 2008 - 2009 Alexander Shaduri <ashaduri 'at' gmail.com>
# License: See LICENSE_zlib.txt file
############################################################################
# Check whether C++ compiler supports overloading of functions
# with function pointer argument differing only in extern "C" specification,
# that is, extern "C" function pointer and C++ function pointer. GCC and
# Intel treat them equally, so no overloads are needed (or accepted)
# there.
# SunCC accepts C++-to-C function pointer assignment in function
# parameters, but not in constructor parameters. To make such
# code work an additional C-function-pointer constructor must be
# specified. Then the constructor itself can make the conversion
# (with a compiler warning though).
# SunCC also disallows C-to-C++ function pointer specification
# for template parameters (I don't remember the exact details).
# If such overloading support is found,
# HAVE_CXX_EXTERN_C_OVERLOAD is defined.
AC_DEFUN([APP_CXX_EXTERN_C_OVERLOAD], [
AC_CACHE_CHECK(whether $CXX accepts extern C function pointer overload, ac_cv_cxx_extern_c_overload, [
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
extern "C" { typedef void (*c_func_t)(void); }
typedef void (*cpp_func_t)(void);
void f1(c_func_t f) { }
void f1(cpp_func_t f) { }
]], [[]])],
[ac_cv_cxx_extern_c_overload=yes], [ac_cv_cxx_extern_c_overload=no])
AC_LANG_POP([])
])
if test "x$ac_cv_cxx_extern_c_overload" = "xyes"; then
AC_DEFINE(HAVE_CXX_EXTERN_C_OVERLOAD, 1,
[Defined to 1 if the C++ complier accepts extern C function pointer overload, 0 otherwise])
else
AC_DEFINE(HAVE_CXX_EXTERN_C_OVERLOAD, 0,
[Defined to 1 if the C++ complier accepts extern C function pointer overload, 0 otherwise])
fi
])
-10
View File
@@ -91,16 +91,6 @@ AX_CXX_GCC_ABI_DEMANGLE
# detect __gnu_cxx::__verbose_terminate_handler (defines HAVE_VERBOSE_TERMINATE_HANDLER.)
AC_CXX_VERBOSE_TERMINATE_HANDLER
# detect __func__ support (defines HAVE_CXX___func__)
APP_CXX___func__
# detect __FUNCTION__ support (defines HAVE_CXX___FUNCTION__)
APP_CXX___FUNCTION__
# detect if the compiler accepts extern "C" function pointer overloads
# (defines HAVE_CXX_EXTERN_C_OVERLOAD)
APP_CXX_EXTERN_C_OVERLOAD
# -------------------------------------------------------------------------------------
@@ -17,12 +17,6 @@
#include "hz/hz_config.h" // feature test macros (ENABLE_*)
// Old glibmm versions had exceptions but didn't define this at all.
// New ones define it to 0 if there are no glibmm exceptions.
#if !defined GLIBMM_EXCEPTIONS_ENABLED || GLIBMM_EXCEPTIONS_ENABLED
#include <memory> // std::auto_ptr
#endif
#include "hz/debug.h"
#include "hz/instance_manager.h"
#include "hz/res_data.h"
@@ -60,7 +54,6 @@ inline bool app_ui_res_create_from(app_ui_res_ref_t& ref,
return false;
}
#if !defined GLIBMM_EXCEPTIONS_ENABLED || GLIBMM_EXCEPTIONS_ENABLED
try {
// ref->add_from_file("main_window.ui");
ref->add_from_string(reinterpret_cast<const char*>(buf), static_cast<gsize>(buf_size));
@@ -70,17 +63,6 @@ inline bool app_ui_res_create_from(app_ui_res_ref_t& ref,
return false;
}
#else
std::auto_ptr<Glib::BuilderError> error;
ref->add_from_string(reinterpret_cast<const char*>(buf), static_cast<gsize>(buf_size),"", "", error);
if (error.get()) {
error_msg = error->what();
return false;
}
#endif
return true;
}
-7
View File
@@ -83,13 +83,6 @@ Additionally, it may be included through compiler's "-include" option
// or none of the above to disable debug output completely.
// -- hz/i18n.h settings.
//
#ifndef ENABLE_NLS
#define ENABLE_NLS 0
#endif
// -- hz/res_data.h settings.
//
#ifndef HZ_ENABLE_COMPILED_RES_DATA
+4 -4
View File
@@ -6,10 +6,10 @@ noinst_HEADERS = ascii.h \
data_file.h debug.h env_tools.h errno_string.h error.h error_holder.h \
format_unit.h fs_common.h fs_dir.h fs_dir_platform.h fs_error_holder.h \
fs_file.h fs_path.h fs_path_utils.h fs_tools.h hz_config.h i18n.h \
instance_manager.h intrusive_ptr.h launch_url.h local_algo.h \
locale_tools.h portable_snprintf.h process_signal.h \
res_data.h scoped_array.h scoped_ptr.h stream_cast.h \
string_algo.h string_num.h string_sprintf.h string_sprintf_macros.h string_wcmatch.h \
instance_manager.h intrusive_ptr.h launch_url.h \
locale_tools.h process_signal.h \
res_data.h scoped_ptr.h stream_cast.h \
string_algo.h string_num.h string_sprintf.h string_wcmatch.h \
system_specific.h type_categories.h type_properties.h win32_tools.h
bin2ascii_encoder_test_SOURCES = bin2ascii_encoder_test.cpp
+4 -5
View File
@@ -18,7 +18,6 @@
#if defined _WIN32
#include <windows.h> // winapi stuff
#include "scoped_array.h"
#include "win32_tools.h" // win32_*
#elif defined ENABLE_GLIB && ENABLE_GLIB
#include <glib.h>
@@ -67,8 +66,7 @@ inline bool env_get_value(const std::string& name, std::string& value)
len = 2;
}
hz::scoped_array<wchar_t> wvalue(new wchar_t[len]);
auto wvalue = std::make_unique<wchar_t[]>(len);
if (GetEnvironmentVariableW(wname.c_str(), wvalue.get(), len) != len - 1) { // failure
return false;
}
@@ -79,8 +77,7 @@ inline bool env_get_value(const std::string& name, std::string& value)
len = ExpandEnvironmentStringsW(wvalue.get(), dummy, 2); // get the needed length
if (len > 0) { // not failure
hz::scoped_array<wchar_t> wvalue_exp(new wchar_t[len]);
auto wvalue_exp = std::make_unique<wchar_t[]>(len);
if (ExpandEnvironmentStringsW(wvalue.get(), wvalue_exp.get(), len) != len) // failure
return false;
@@ -102,6 +99,8 @@ inline bool env_get_value(const std::string& name, std::string& value)
return true;
#else
// Since C++11, getenv has to be thread-safe (unless some other thread is
// modifying the environment).
const char* v = std::getenv(name.c_str());
if (!v)
return false;
+6 -8
View File
@@ -17,6 +17,7 @@
#include <string>
#include <cstddef> // std::size_t
#include <cstdarg> // for stdarg.h, va_start, std::va_list and friends.
#include <cstdio> // std::snprintf
#if defined ENABLE_GLIB && ENABLE_GLIB
#include <glib.h> // g_strerror(), g_strsignal()
@@ -46,9 +47,6 @@
#endif
#include "portable_snprintf.h" // portable_snprintf
// Compilation options:
// - Define ENABLE_GLIB to 1 to enable glib-related code (portable errno messages)
@@ -91,10 +89,10 @@ inline std::string errno_string(int errno_value)
msg = buf;
} else { // errno is set on error
if (errno == EINVAL) { // errno may be a macro
portable_snprintf(buf, buf_size, "Unknown errno: %d.", errno_value);
std::snprintf(buf, buf_size, "Unknown errno: %d.", errno_value);
msg = buf;
} else if (errno == ERANGE) {
portable_snprintf(buf, buf_size, "Insufficient buffer to store description for errno: %d.", errno_value);
std::snprintf(buf, buf_size, "Insufficient buffer to store description for errno: %d.", errno_value);
msg = buf;
}
}
@@ -104,14 +102,14 @@ inline std::string errno_string(int errno_value)
if (rmsg) {
msg = rmsg;
} else {
portable_snprintf(buf, buf_size, "Error while getting description for errno: %d.", errno_value);
std::snprintf(buf, buf_size, "Error while getting description for errno: %d.", errno_value);
msg = buf;
}
#elif defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
wchar_t msg_buf[128] = {0}; // MS docs don't say exactly, but it's somewhere in 80-100 range.
if (_wcserror_s(msg_buf, 128, errno_value) != 0) { // always 0-terminated
portable_snprintf(buf, buf_size, "Error while getting description for errno: %d.", errno_value);
std::snprintf(buf, buf_size, "Error while getting description for errno: %d.", errno_value);
msg = buf;
}
msg = hz::win32_utf16_to_utf8(msg_buf);
@@ -122,7 +120,7 @@ inline std::string errno_string(int errno_value)
if (m) {
msg = m;
} else {
portable_snprintf(buf, buf_size, "Error while getting description for errno: %d.", errno_value);
std::snprintf(buf, buf_size, "Error while getting description for errno: %d.", errno_value);
msg = buf;
}
+1 -1
View File
@@ -265,7 +265,7 @@ class Error<int> : public ErrorCodeHolder<int> {
} else if (type == "signal") {
// hz::signal_string should be translated already
message = HZ__("Child exited with signal: ") + hz::signal_to_string(code_);
message = "Child exited with signal: " + hz::signal_to_string(code_);
} else { // nothing else supported here. use constructor with a message.
DBG_ASSERT(0);
+3 -3
View File
@@ -17,8 +17,8 @@
#include <string>
#include <vector>
#include <sys/types.h> // dirent needs this
#include <algorithm>
#include "local_algo.h" // shell_sort
#include "string_wcmatch.h" // string_wcmatch
#include "fs_path.h" // Path
@@ -876,7 +876,7 @@ bool Dir::list(Container& put_here, bool put_with_path, SortFunctor sort_func, F
sort_func.set_dir(this->get_path());
if (sort_using_paths) {
hz::shell_sort(path_results.begin(), path_results.end(), sort_func);
std::sort(path_results.begin(), path_results.end(), sort_func);
for (list_path_list_t::const_iterator iter = path_results.begin(); iter != path_results.end(); ++iter) {
if (put_with_path) {
@@ -887,7 +887,7 @@ bool Dir::list(Container& put_here, bool put_with_path, SortFunctor sort_func, F
}
} else {
hz::shell_sort(string_results.begin(), string_results.end(), sort_func);
std::sort(string_results.begin(), string_results.end(), sort_func);
for (list_string_list_t::const_iterator iter = string_results.begin(); iter != string_results.end(); ++iter) {
if (put_with_path) {
+4 -4
View File
@@ -107,15 +107,15 @@ inline std::string directory_entry_name(directory_entry_handle_type entry)
namespace internal {
struct DirectoryEntry {
const wchar_t* d_name; // this is owned by Directory's data field. utf-16.
const wchar_t* d_name = 0; // this is owned by Directory's data field. utf-16.
};
struct Directory {
struct _wfinddata_t data; // entry data as given by _wfindfirst().
DirectoryEntry entry; // current directory entry
intptr_t handle; // directory handle as returned by _wfindfirst().
long status; // 0 - not started, -1 - off the end, positive - 0-based index of next entry.
wchar_t full_pattern[MAX_PATH + 3]; // directory search pattern + "\\*"
intptr_t handle = 0; // directory handle as returned by _wfindfirst().
long status = 0; // 0 - not started, -1 - off the end, positive - 0-based index of next entry.
wchar_t full_pattern[MAX_PATH + 3] = {0}; // directory search pattern + "\\*"
};
}
-1
View File
@@ -102,7 +102,6 @@ One has to use _fseeki64() and friends explicitly.
#include "fs_path.h" // FsPath
#ifdef _WIN32
#include "scoped_array.h" // hz::scoped_array
#include "win32_tools.h" // hz::win32_utf8_to_utf16
#endif
-1
View File
@@ -28,7 +28,6 @@
#ifdef _WIN32
#include "win32_tools.h" // win32_* stuff
#include "scoped_array.h" // hz::scoped_array
#endif
-79
View File
@@ -80,18 +80,6 @@ HZ library internal implementation helpers.
/// \def HAVE_CXX_EXTERN_C_OVERLOAD
/// Defined to 0 or 1. If 1, compiler supports overloading on extern "C" function pointer arguments.
#ifndef HAVE_CXX_EXTERN_C_OVERLOAD
#ifdef __SUNPRO_CC
#define HAVE_CXX_EXTERN_C_OVERLOAD 1
#else
#define HAVE_CXX_EXTERN_C_OVERLOAD 0
#endif
#endif
/// \def HAVE_VERBOSE_TERMINATE_HANDLER
/// Defined to 0 or 1. If 1, compiler supports __gnu_cxx::__verbose_terminate_handler.
@@ -187,72 +175,6 @@ HZ library internal implementation helpers.
/// \def HAVE_ISO_STDIO
/// Defined to 0 or 1. If 1, the *printf() family (but not _*printf() or *printf_s()) behaves
/// according to ISO specification in terms of 0-termination, return value
/// and accepting %lld, %llu and %Lf format specifiers.
/// Note: If using mingw runtime >= 3.15 and __USE_MINGW_ANSI_STDIO,
/// mingw supports both C99/POSIX and msvcrt format specifiers.
/// This includes proper printing of long double (%Lf), %lld and %llu, etc...
/// This does _not_ affect _snprintf() and similar non-standard functions.
#ifndef HAVE_ISO_STDIO
// On win32, assume only with mingw with ansi/iso extensions.
// for others, assume it's always there.
#if !defined _WIN32 || ( defined __GNUC__ && \
(!defined __NO_ISOCEXT || defined __USE_MINGW_ANSI_STDIO) )
#define HAVE_ISO_STDIO 1
#else
#define HAVE_ISO_STDIO 0
#endif
#endif
/// \def HAVE__SNPRINTF
/// Defined to 0 or 1. If 1, the compiler has Win32's _snprintf (broken 0-termination).
#ifndef HAVE__SNPRINTF
#if defined _WIN32
#define HAVE__SNPRINTF 1
#else
#define HAVE__SNPRINTF 0
#endif
#endif
/// \def HAVE__VSNPRINTF
/// Defined to 0 or 1. If 1, the compiler has Win32's _vsnprintf (broken 0-termination).
#ifndef HAVE__VSNPRINTF
#if defined _WIN32
#define HAVE__VSNPRINTF 1
#else
#define HAVE__VSNPRINTF 0
#endif
#endif
/// \def HAVE_SNPRINTF_S
/// Defined to 0 or 1. If 1, the compiler has snprintf_s (msvc 2005/8.0).
#ifndef HAVE_SNPRINTF_S
#if defined _MSC_VER && _MSC_VER >= 1400
#define HAVE_SNPRINTF_S 1
#else
#define HAVE_SNPRINTF_S 0
#endif
#endif
/// \def HAVE_VSNPRINTF_S
/// Defined to 0 or 1. If 1, the compiler has vsnprintf_s (msvc 2005/8.0).
#ifndef HAVE_VSNPRINTF_S
#if defined _MSC_VER && _MSC_VER >= 1400
#define HAVE_VSNPRINTF_S 1
#else
#define HAVE_VSNPRINTF_S 0
#endif
#endif
/// \def HAVE_VASPRINTF
/// Defined to 0 or 1. If 1, the compiler has vasprintf() (GNU/glibc extension).
#ifndef HAVE_VASPRINTF
@@ -265,7 +187,6 @@ HZ library internal implementation helpers.
/// \def HAVE_REENTRANT_LOCALTIME
/// Defined to 0 or 1. If 1, localtime() is reentrant.
#ifndef HAVE_REENTRANT_LOCALTIME
-1
View File
@@ -20,7 +20,6 @@
#ifdef _WIN32
#include <windows.h> // seems to be needed by shellapi.h
#include <shellapi.h> // ShellExecuteW()
#include "scoped_array.h"
#include "win32_tools.h" // hz::win32_utf8_to_utf16
#else
#include "scoped_ptr.h"
-150
View File
@@ -1,150 +0,0 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_LOCAL_ALGO_H
#define HZ_LOCAL_ALGO_H
#include "hz_config.h" // feature macros
#include <cstddef> // std::ptrdiff_t
namespace hz {
/**
\file
These standard-like algorithms are here to avoid including huge
standard headers in a header-only library.
*/
// -------------------------------- Shell Sort
namespace internal {
/// Helper for shell_sort
template<class T>
struct shell_sort_helper { // works for operators
typedef typename T::value_type value_type;
};
/// Specialization
template<class T>
struct shell_sort_helper<T*> { // needed for C arrays
typedef T value_type;
};
} // ns internal
/// Shell sort. Works for most STL containers.
/// Shell sort is one of the fastest on small datasets (<1000),
/// and has a small memory footprint.
template<class RandomIter> inline
void shell_sort(RandomIter first, RandomIter last)
{
const std::ptrdiff_t n = last - first;
for (std::ptrdiff_t gap = n / 2; 0 < gap; gap /= 2) {
for (std::ptrdiff_t i = gap; i < n; i++) {
for (std::ptrdiff_t j = i - gap; 0 <= j; j -= gap) {
if ( *(first+j+gap) < *(first+j) ) { // swap them
typename internal::shell_sort_helper<RandomIter>::value_type temp = *(first+j);
*(first+j) = *(first+j+gap);
*(first+j+gap) = temp;
}
}
}
}
}
/// Same as the other shell_sort(), but with custom comparator function
template<class RandomIter, class Comparator> inline
void shell_sort(RandomIter first, RandomIter last, Comparator less_than_func)
{
const std::ptrdiff_t n = last - first;
for (std::ptrdiff_t gap = n / 2; 0 < gap; gap /= 2) {
for (std::ptrdiff_t i = gap; i < n; i++) {
for (std::ptrdiff_t j = i - gap; 0 <= j; j -= gap) {
if ( less_than_func(*(first+j+gap), *(first+j)) ) { // swap them
typename internal::shell_sort_helper<RandomIter>::value_type temp = *(first+j);
*(first+j) = *(first+j+gap);
*(first+j+gap) = temp;
}
}
}
}
}
/// Binary search.
/// \return iterator to found element, or \c end if not found.
template<typename RandomIter, typename ValueType> inline
RandomIter returning_binary_search(RandomIter begin, RandomIter end, const ValueType& value)
{
RandomIter initial_end = end;
RandomIter middle;
while (begin < end) {
middle = begin + ((end - begin - 1) / 2);
if (value < *middle) {
end = middle;
} else if (*middle < value) {
begin = middle + 1;
} else {
return middle;
}
}
return initial_end;
}
/// Binary search with custom comparator.
/// \return iterator to found element, or \c end if not found.
template<typename RandomIter, typename ValueType, typename LessComparator> inline
RandomIter returning_binary_search(RandomIter begin, RandomIter end,
const ValueType& value, LessComparator comp)
{
RandomIter initial_end = end;
RandomIter middle;
while (begin < end) {
middle = begin + ((end - begin - 1) / 2);
if (comp(value, *middle)) {
end = middle;
} else if (comp(*middle, value)) {
begin = middle + 1;
} else {
return middle;
}
}
return initial_end;
}
} // ns
#endif
/// @}
-195
View File
@@ -1,195 +0,0 @@
/**************************************************************************
Copyright:
(C) 2009 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_PORTABLE_SNPRINTF_H
#define HZ_PORTABLE_SNPRINTF_H
#include "hz_config.h" // feature macros
/**
\file
Compilation options:
- Define \c ENABLE_GLIB to 1 to enable glib-related code (portable ISO-compatible (v)snprintf).
Keep in mind that these format types are non-portable (the first one is MS variant,
the second one is standard):
- %I64d, %lld (long long int),
- %I64u, %llu (unsigned long long int),
- %f, %Lf (long double; needs casting to double under non-ANSI mingw if using %f).
*/
namespace hz {
// Note: There are macros, so they are not namespaced.
/// \def HAVE_PORTABLE_SNPRINTF_MS
/// If 1, portable_snprintf() and portable_vsnprintf() accept I64d, I64u.
/// Users are expected to check this macro to see if the format is supported.
/// \def HAVE_PORTABLE_SNPRINTF_ISO
/// If 1, portable_snprintf() and portable_vsnprintf() accept lld, llu, Lf.
/// Users are expected to check this macro to see if the format is supported.
/// \def portable_snprintf(buf, buf_size, ...)
/// snprintf() wrapper that always behaves according to ISO standard in terms of 0-termination.
/// Note that this is a macro, and therefore not namespaced.
/// Use it like this:
/// \code void portable_snprintf(char *str, size_t size, const char *format, ...); \endcode
#if defined ENABLE_GLIB && ENABLE_GLIB
#include <glib.h> // g_snprintf
// It's ISO-compatible
#define portable_snprintf(buf, buf_size, ...) \
(void)g_snprintf((buf), (buf_size), __VA_ARGS__)
#define HAVE_PORTABLE_SNPRINTF_MS 0
#define HAVE_PORTABLE_SNPRINTF_ISO 1
#elif defined HAVE_ISO_STDIO && HAVE_ISO_STDIO
// mingw/ISO, all non-windows platforms.
#include <cstdio> // for cstdio
#include <stdio.h> // snprintf
#define portable_snprintf(buf, buf_size, ...) \
(void)snprintf((buf), (buf_size), __VA_ARGS__)
// mingw/ISO has both the MS and ISO specifiers
#if defined _WIN32 && defined __GNUC__
#define HAVE_PORTABLE_SNPRINTF_MS 1
#else
#define HAVE_PORTABLE_SNPRINTF_MS 0
#endif
#define HAVE_PORTABLE_SNPRINTF_ISO 1
#elif defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
#include <cstdio> // for cstdio
#include <stdio.h> // _snprintf_s
// writes at most buf_size bytes, always including 0.
#define portable_snprintf(buf, buf_size, ...) \
(void)_snprintf_s((buf), (buf_size), _TRUNCATE, __VA_ARGS__)
#define HAVE_PORTABLE_SNPRINTF_MS 1
#define HAVE_PORTABLE_SNPRINTF_ISO 0
#elif defined HAVE__SNPRINTF && HAVE__SNPRINTF
// Prefer snprintf() to _snprintf() if we're sure it's good.
// Note that old versions of mingw used to define snprintf() as _snprintf(),
// which is not proper.
#include <cstdio> // for cstdio
#include <stdio.h> // _snprintf
// _snprintf() writes at most buf_size-1 bytes. the buffer should be zeroed out
// beforehand.
#define portable_snprintf(buf, buf_size, ...) \
(void)((_snprintf((buf), (buf_size) - 1, __VA_ARGS__) == ((buf_size) - 1)) && ((buf)[(buf_size)-1] = '\0'))
#define HAVE_PORTABLE_SNPRINTF_MS 0
#define HAVE_PORTABLE_SNPRINTF_ISO 1
#else
#error Cannot find suitable snprintf() implementation for portable_snprintf()
#endif
/// \def portable_vsnprintf(buf, buf_size, ...)
/// vsnprintf() wrapper that always behaves according to ISO standard in terms of 0-termination.
/// Note that this is a macro, and therefore not namespaced.
/// Use it like this:
/// \code void portable_vsnprintf(char *str, size_t size, const char *format, va_list ap); \endcode
#if defined ENABLE_GLIB && ENABLE_GLIB
#include <glib.h> // g_vsnprintf
// It's ISO-compatible
#define portable_vsnprintf(buf, buf_size, format, ap) \
(void)g_vsnprintf((buf), (buf_size), (format), (ap))
#define HAVE_PORTABLE_VSNPRINTF_MS 0
#define HAVE_PORTABLE_VSNPRINTF_ISO 1
#elif defined HAVE_ISO_STDIO && HAVE_ISO_STDIO
#include <cstdio> // for cstdio
#include <stdio.h> // vsnprintf (mingw, posix(?))
#include <cstdarg> // for cstdarg
#include <stdarg.h> // vsnprintf (gnu)
#define portable_vsnprintf(buf, buf_size, format, ap) \
(void)vsnprintf((buf), (buf_size), (format), (ap))
// mingw/ISO has both the MS and ISO specifiers
#if defined _WIN32 && defined __GNUC__
#define HAVE_PORTABLE_VSNPRINTF_MS 1
#else
#define HAVE_PORTABLE_VSNPRINTF_MS 0
#endif
#define HAVE_PORTABLE_VSNPRINTF_ISO 1
#elif defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
#include <cstdio> // for cstdio
#include <stdio.h> // _vsnprintf_s
// writes at most buf_size bytes, always including 0.
#define portable_vsnprintf(buf, buf_size, format, ap) \
(void)vsnprintf_s((buf), (buf_size), _TRUNCATE, (format), (ap))
#define HAVE_PORTABLE_VSNPRINTF_MS 1
#define HAVE_PORTABLE_VSNPRINTF_ISO 0
#elif defined HAVE__VSNPRINTF && HAVE__VSNPRINTF
// prefer snprintf() to _snprintf() if we're sure it's good.
#include <cstdio> // for cstdio
#include <stdio.h> // _vsnprintf
#include <cstdarg> // for cstdarg
#include <stdarg.h> // _vsnprintf
// _vsnprintf() writes at most buf_size-1 bytes. the buffer should be zeroed out
// beforehand.
// Note that MS's vsnprintf() (which is the same as their _vsnprintf())
// doesn't always write 0.
// We use _vsnprintf() instead of vsnprintf() to avoid using the proper vsnprintf()
// by chance (_vsnprintf() is always broken, vsnprintf() may not be).
#define portable_vsnprintf(buf, buf_size, format, ap) \
(void)((_vsnprintf((buf), (buf_size) - 1, (format), (ap)) == ((buf_size) - 1)) && ((buf)[(buf_size)-1] = '\0'))
#define HAVE_PORTABLE_VSNPRINTF_MS 1
#define HAVE_PORTABLE_VSNPRINTF_ISO 0
#else
#error Cannot find suitable vsnprintf() implementation for portable_vsnprintf()
#endif
} // ns
#endif
/// @}
+3 -4
View File
@@ -15,6 +15,7 @@
#include "hz_config.h" // feature macros
#include <string>
#include <cstdio> // std::snprintf
#if defined ENABLE_GLIB && ENABLE_GLIB
#include <glib.h> // g_strsignal()
@@ -35,8 +36,6 @@
#include <signal.h> // kill()
#endif
#include "portable_snprintf.h" // portable_snprintf
/**
@@ -129,7 +128,7 @@ inline std::string signal_to_string(int signal_value)
#elif defined _WIN32
char buf[64] = {0};
portable_snprintf(buf, 64, "Unknown signal: %d.", signal_value);
std::snprintf(buf, 64, "Unknown signal: %d.", signal_value);
msg = buf;
#else // no glib and not win32
@@ -139,7 +138,7 @@ inline std::string signal_to_string(int signal_value)
msg = m;
} else {
char buf[64] = {0};
portable_snprintf(buf, 64, "Unknown signal: %d.", signal_value);
std::snprintf(buf, 64, "Unknown signal: %d.", signal_value);
msg = buf;
}
#endif
+11 -11
View File
@@ -51,9 +51,9 @@ Configuration macros: HZ_ENABLE_COMPILED_RES_DATA (0 | 1).
return std::string(); \
return std::string(reinterpret_cast<const char*>(buf), size); \
} \
const unsigned char* buf; \
unsigned int size; \
const char* root_name; \
const unsigned char* buf = 0; \
unsigned int size = 0; \
const char* root_name = 0; \
}
@@ -70,7 +70,7 @@ Configuration macros: HZ_ENABLE_COMPILED_RES_DATA (0 | 1).
/// to register the data file search paths.
#define HZ_RES_DATA_LOADED_INIT_NAMED(res_name, data_file, class_name) \
struct class_name { \
class_name() : buf(0), size(0), root_name(0) \
class_name() \
{ \
std::string path = hz::data_file_find(data_file); \
if (path.empty()) \
@@ -99,9 +99,9 @@ Configuration macros: HZ_ENABLE_COMPILED_RES_DATA (0 | 1).
return std::string(); \
return std::string(reinterpret_cast<const char*>(buf), size); \
} \
const unsigned char* buf; \
unsigned int size; \
const char* root_name; \
const unsigned char* buf = 0; \
unsigned int size = 0; \
const char* root_name = 0; \
}
@@ -114,15 +114,15 @@ Configuration macros: HZ_ENABLE_COMPILED_RES_DATA (0 | 1).
/// Dummy fallback
#define HZ_RES_DATA_DUMMY_INIT_NAMED(res_name, dummy, class_name) \
struct class_name { \
class_name() : buf(0), size(0), root_name(#res_name) \
class_name() : root_name(#res_name) \
{ } \
std::string get_string() const \
{ \
return std::string(); \
} \
const unsigned char* buf; \
unsigned int size; \
const char* root_name; \
const unsigned char* buf = 0; \
unsigned int size = 0; \
const char* root_name = 0; \
}
/// Dummy fallback
-161
View File
@@ -1,161 +0,0 @@
/**************************************************************************
Copyright:
(C) 1998 - 2010 Greg Colvin and Beman Dawes
(C) 2001 - 2010 Peter Dimov
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_boost_1_0.txt file
***************************************************************************/
/// \file
/// \author Greg Colvin and Beman Dawes
/// \author Peter Dimov
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_SCOPED_ARRAY_H
#define HZ_SCOPED_ARRAY_H
#include "hz_config.h" // feature macros
/**
\file
Scoped non-reference-counting auto-deletign array.
Based on boost::scoped_array.
Original notes and copyright info follow:
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// http://www.boost.org/libs/smart_ptr/scoped_array.htm
//
*/
#include <cstddef> // std::ptrdiff_t
#include <cassert>
#ifndef ASSERT // assert() is undefined if NDEBUG is defined.
#define ASSERT(a) assert(a)
#endif
namespace hz {
/// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
/// is guaranteed, either on destruction of the scoped_array or via an explicit
/// reset(). Use shared_array or std::vector if your needs are more complex.
template<typename T>
class scoped_array { // noncopyable
private:
T* ptr; ///< The underlying array pointer
/// Private copy constructor
scoped_array(const scoped_array&);
/// Private assignment operator
scoped_array& operator=(const scoped_array&);
typedef scoped_array<T> this_type; ///< Own type
typedef T* this_type::*unspecified_bool_type; ///< Helper for bool conversions
/// Private operator
void operator==(const scoped_array&) const;
/// Private operator
void operator!=(const scoped_array&) const;
public:
/// Underlying type (without pointer)
typedef T element_type;
/// Constructor, gets hold of the array ownership
explicit scoped_array(T* p = 0) : ptr(p) // never throws
{ }
/// Destructor, deletes the array
~scoped_array() // never throws
{
delete[] (ptr);
ptr = 0; // exception-safety (needed here?)
}
/// Delete the old array and switch to the new one
void reset(T* p = 0) // never throws
{
ASSERT(p == 0 || p != ptr); // catch self-reset errors
this_type(p).swap(*this);
}
/// Element access
T& operator[](std::ptrdiff_t i) const // never throws
{
ASSERT(ptr != 0);
ASSERT(i >= 0);
return ptr[i];
}
/// Get the underlying pointer
T* get() const // never throws
{
return ptr;
}
/// Get a reference to the stored pointer.
/// Useful for passing to functions who expect T**.
T*& get_ref() // never throws
{
return ptr;
}
/// Bool-like conversion
operator unspecified_bool_type () const
{
return ptr == 0 ? 0 : &this_type::ptr;
}
/// Null-check
bool operator! () const // never throws
{
return ptr == 0;
}
/// Swap with another array
void swap(scoped_array& b) // never throws
{
T * tmp = b.ptr;
b.ptr = ptr;
ptr = tmp;
}
};
/// Swap two arrays
template<typename T> inline
void swap(scoped_array<T>& a, scoped_array<T>& b) // never throws
{
a.swap(b);
}
} // ns
#endif // hg
/// @}
+14 -89
View File
@@ -19,33 +19,17 @@
#include <string>
#include <cstdarg> // for stdarg.h, va_start, std::va_list and friends.
#include <cstdarg> // for va_start, std::va_list and friends.
#include <cstdio>
#include <cstdlib> // std::free
#if defined ENABLE_GLIB && ENABLE_GLIB
#include <glib.h> // g_strdup_vprintf(), g_printf_string_upper_bound()
#elif defined HAVE_VASPRINTF && HAVE_VASPRINTF && defined HAVE_ISO_STDIO && HAVE_ISO_STDIO
// GNU
#include <cstdio> // for stdio.h
#elif defined HAVE_VASPRINTF && HAVE_VASPRINTF
#include <stdio.h> // vasprintf()
#include <cstdlib> // std::free
#elif defined HAVE_ISO_STDIO && HAVE_ISO_STDIO
// POSIX, mingw/ISO
#include <cstdio> // for stdio.h
#include <stdio.h> // vsnprintf()
#include <stdarg.h> // vsnprintf()
#elif defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
// msvc 2005 and later
#include <cstdio> // for stdio.h
#include <stdio.h> // vsnprintf_s()
#include <stdarg.h> // vsnprintf_s()
#else
// mingw/no-ISO, msvc, possibly other old systems
#include <cstdio> // for stdio.h
#include <stdio.h> // _vsnprintf()
#include <stdarg.h> // _vsnprintf()
#endif
#include "string_sprintf_macros.h"
#include "system_specific.h"
/**
@@ -77,19 +61,19 @@ namespace hz {
/// Get the buffer size required to safely allocate a buffer (including terminating 0) and call vsnprintf().
inline int string_vsprintf_get_buffer_size(const char* format, std::va_list ap) HZ_FUNC_STRING_SPRINTF_CHECK(1, 0);
inline int string_vsprintf_get_buffer_size(const char* format, std::va_list ap) HZ_FUNC_PRINTF_ISO_CHECK(1, 0);
/// Same as string_vsprintf_get_buffer_size(), but using varargs.
inline int string_sprintf_get_buffer_size(const char* format, ...) HZ_FUNC_STRING_SPRINTF_CHECK(1, 2);
inline int string_sprintf_get_buffer_size(const char* format, ...) HZ_FUNC_PRINTF_ISO_CHECK(1, 2);
/// Auto-allocating std::string-returning portable vsprintf
inline std::string string_vsprintf(const char* format, std::va_list ap) HZ_FUNC_STRING_SPRINTF_CHECK(1, 0);
inline std::string string_vsprintf(const char* format, std::va_list ap) HZ_FUNC_PRINTF_ISO_CHECK(1, 0);
/// Same as string_vsprintf(), but using varargs
inline std::string string_sprintf(const char* format, ...) HZ_FUNC_STRING_SPRINTF_CHECK(1, 2);
inline std::string string_sprintf(const char* format, ...) HZ_FUNC_PRINTF_ISO_CHECK(1, 2);
@@ -105,59 +89,14 @@ inline int string_vsprintf_get_buffer_size(const char* format, std::va_list ap)
// the glib version returns gsize
return static_cast<int>(g_printf_string_upper_bound(format, ap));
#elif defined HAVE_ISO_STDIO && HAVE_ISO_STDIO
// In C99/POSIX, vsnprintf() returns the number of bytes it could have written
#else
// In C++11, vsnprintf() returns the number of bytes it could have written
// (without \0) if buffer was large enough.
// This includes mingw/ISO.
char c = 0;
const int size = vsnprintf(&c, 1, format, ap); // C99 and others
const int size = std::vsnprintf(nullptr, 0, format, ap); // C99 and others
if (size < 0)
return -1;
return size + 1; // that +1 is for \0.
#else
// Unfortunately, MS (maybe some very old systems as well) return -1 if buffer
// is not large enough, so we have to use incremental reallocation until it fits.
errno = 0; // reset
int buf_size = 32;
int ret = -1;
do {
char* buf = new char[buf_size];
#if defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
const int size = vsnprintf_s(buf, buf_size, buf_size - 1, format, ap); // writes (buf_size - 1) chars, appends 0.
#elif defined HAVE__VSNPRINTF && HAVE__VSNPRINTF
// Prefer _vsnprintf() to vsnprintf() as MS may change the latter eventually.
const int size = _vsnprintf(buf, buf_size, format, ap); // writes buf_size chars, including 0 (if it fits).
#else
const int size = vsnprintf(buf, buf_size, format, ap); // assume same as above
#endif
if (size == -1) {
if (errno != 0) { // error
break; // -1
} else { // doesn't fit, increase size.
buf_size *= 4; // continue
}
} else if (size <= buf_size) {
ret = size + 1; // for 0, as the returned value doesn't contain the 0.
break;
} else { // huh?
break; // -1, treat as error
}
delete[] buf;
} while (true);
return ret;
#endif
}
@@ -184,11 +123,7 @@ inline std::string string_vsprintf(const char* format, std::va_list ap)
if (buf)
g_free(buf);
#elif defined HAVE_VASPRINTF && HAVE_VASPRINTF && defined HAVE_ISO_STDIO && HAVE_ISO_STDIO
// We check both vasprintf() and ISO compliance above to ensure that
// string_vsnprintf() and string_vsprintf_get_buffer_size() can work with
// the same format string.
#elif defined HAVE_VASPRINTF && HAVE_VASPRINTF
std::string ret;
char* str = 0;
if (vasprintf(&str, format, ap) > 0) // GNU extension
@@ -202,19 +137,9 @@ inline std::string string_vsprintf(const char* format, std::va_list ap)
if (size > 0) {
char* buf = new char[size];
int written = 0;
#if defined HAVE_ISO_STDIO && HAVE_ISO_STDIO
// we could use vsprintf(), but it's deemed unsafe in many environments.
written = vsnprintf(buf, size, format, ap); // writes size chars, including 0.
#elif defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
written = vsnprintf_s(buf, size, size - 1, format, ap); // writes (size - 1) chars, appends 0.
written = std::vsnprintf(buf, size, format, ap); // writes size chars, including 0.
#elif defined HAVE__VSNPRINTF && HAVE__VSNPRINTF
written = _vsnprintf(buf, size, format, ap); // writes size chars, including 0.
#else
// Same as the first one, to ensure that the order matches that of string_vsprintf_get_buffer_size().
written = vsnprintf(buf, size, format, ap); // writes size chars, including 0.
#endif
if (written > 0)
ret = buf;
delete[] buf;
@@ -1,81 +0,0 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
/// \author Alexander Shaduri
/// \ingroup hz
/// \weakgroup hz
/// @{
#ifndef HZ_STRING_SPRINTF_MACROS_H
#define HZ_STRING_SPRINTF_MACROS_H
#include "hz_config.h" // feature macros
#include "system_specific.h" // HZ_FUNC_PRINTF_*_CHECK
/**
\file
This is a helper file for string_sprintf.h. It is useful if you need
the macros only, but not the implementation (useful for header files).
*/
/// \def HAVE_STRING_SPRINTF_MS
/// whether the MS (%I64d and %I64u) specifiers are supported.
/// \def HAVE_STRING_SPRINTF_ISO
/// whether the ISO (%lld, %llu, %Lf) specifiers are supported.
#if defined ENABLE_GLIB && ENABLE_GLIB
#define HAVE_STRING_SPRINTF_MS 0
#define HAVE_STRING_SPRINTF_ISO 1
#elif defined HAVE_ISO_STDIO && HAVE_ISO_STDIO
// mingw/ISO has both the MS and ISO specifiers
#if defined _WIN32 && defined __GNUC__
#define HAVE_STRING_SPRINTF_MS 1
#else
#define HAVE_STRING_SPRINTF_MS 0
#endif
#define HAVE_STRING_SPRINTF_ISO 1
#elif defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
#define HAVE_STRING_SPRINTF_MS 1
#define HAVE_STRING_SPRINTF_ISO 0
#elif defined HAVE__VSNPRINTF && HAVE__VSNPRINTF
#define HAVE_STRING_SPRINTF_MS 0
#define HAVE_STRING_SPRINTF_ISO 1
#else
#warning Cannot detect vsnprintf() availability
#define HAVE_STRING_SPRINTF_MS 0
#define HAVE_STRING_SPRINTF_ISO 0
#endif
// HZ_FUNC_STRING_SPRINTF_CHECK - gcc printf format attribute checker,
// configured according to MS or ISO features (prefers ISO over MS).
#if HAVE_STRING_SPRINTF_ISO
#define HZ_FUNC_STRING_SPRINTF_CHECK(format_idx, check_idx) HZ_FUNC_PRINTF_ISO_CHECK(format_idx, check_idx)
#elif HAVE_STRING_SPRINTF_MS
#define HZ_FUNC_STRING_SPRINTF_CHECK(format_idx, check_idx) HZ_FUNC_PRINTF_MS_CHECK(format_idx, check_idx)
#else
#define HZ_FUNC_STRING_SPRINTF_CHECK(format_idx, check_idx)
#endif
#endif
/// @}
+3 -2
View File
@@ -553,8 +553,9 @@ inline std::wstring win32_user_to_utf16(UINT from_cp, std::string_view from_str,
return std::wstring(); // error in conversion
}
std::wstring res(wide_bufsize, L'\0');
MultiByteToWideChar(from_cp, 0, from_str.data(), from_str.size(), res.data(), res.size());
wchar_t* res = new wchar_t[wide_bufsize + 1];
MultiByteToWideChar(from_cp, 0, from_str.data(), from_str.size(), res, wide_bufsize + 1);
res[wide_bufsize] = L'\0';
if (ok) {
*ok = true;
+2 -2
View File
@@ -19,7 +19,7 @@
#include "hz/system_specific.h"
#include "hz/hz_config.h" // HAVE_CXX_*
#include "hz/string_sprintf_macros.h" // HZ_FUNC_STRING_SPRINTF_CHECK
#include "hz/system_specific.h" // HZ_FUNC_PRINTF_ISO_CHECK
#include "dflags.h"
@@ -61,7 +61,7 @@ std::ostream& debug_out(debug_level::flag level, const std::string& domain);
/// Send a printf-like-formatted string to libdebug stream.
void debug_print(debug_level::flag level, const std::string& domain,
const char* format, ...) HZ_FUNC_STRING_SPRINTF_CHECK(3, 4);
const char* format, ...) HZ_FUNC_PRINTF_ISO_CHECK(3, 4);
/// Send a printf-like-formatted string to libdebug stream. For example: