mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-26 13:55:34 +00:00
Moar porting.
This commit is contained in:
+4
-7
@@ -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
|
||||
])
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 + "\\*"
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win32_tools.h" // win32_* stuff
|
||||
#include "scoped_array.h" // hz::scoped_array
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
@@ -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
|
||||
|
||||
/// @}
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user