Updated to latest libhz.

This commit is contained in:
Alexander Shaduri
2014-05-05 09:20:18 +00:00
parent bbe3bac923
commit c68d017475
17 changed files with 269 additions and 61 deletions
+13 -3
View File
@@ -76,7 +76,14 @@
#include "type_properties.h" // type_is_*, type_make_unsigned
// Disable silly VS warnings
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning)
#pragma warning(disable: 4804) // unsafe use of type 'bool' in operation
#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
#pragma warning(disable: 6328) // 'const char' passed as parameter '1' when 'unsigned char' is required in call to 'isspace'
#endif
// Locale-independent functions for ascii manipulation.
@@ -285,7 +292,7 @@ namespace internal {
// I'm not sure if a flag should be raised at all.
// If anyone knows how to do it portably and reliably, please tell me.
return val;
return float(val);
#endif
@@ -373,7 +380,7 @@ T ascii_strtof(const char* nptr, char** endptr)
ASSERT(locdata);
const char* radix = locdata->decimal_point;
ASSERT(radix);
std::size_t radix_len = std::strlen(radix);
std::size_t radix_len = (radix ? std::strlen(radix) : 0U);
ASSERT(radix_len);
// Check if the locale resembles Classic.
@@ -525,6 +532,9 @@ T ascii_strton(const char* nptr, char** endptr, int base = 0)
} // ns
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif
+10 -3
View File
@@ -24,6 +24,7 @@
#include <glib.h>
#else
#include <cstdlib> // for stdlib.h, std::getenv
#include <cstring> // std::malloc
#include <stdlib.h> // setenv, unsetenv, putenv
#endif
@@ -166,7 +167,10 @@ inline bool env_set_value(const std::string& name, const std::string& value, boo
if (!overwrite && env_get_value(name, oldvalue)) {
return true;
}
return putenv((name + "=" + value).c_str()) == 0;
std::string putenv_arg = name + "=" + value;
char* buf = (char*)std::malloc(putenv_arg.size() + 1);
std::memcpy(buf, putenv_arg.c_str(), putenv_arg.size() + 1);
return putenv(buf) == 0; // returns 0 on success. Potentially leaks, but it is the way putenv() behaves.
#endif
}
@@ -192,12 +196,15 @@ inline bool env_unset_value(const std::string& name)
g_unsetenv(name.c_str()); // returns void. may not be thread-safe!
return true;
#elif !(defined HAVE_SETENV && HAVE_SETENV)
#elif defined HAVE_SETENV && HAVE_SETENV
// unsetenv returns -1 on error with errno EINVAL set (invalid char in name).
return unsetenv(name.c_str()) == 0;
#else
return putenv((name + "=").c_str()) == 0; // returns 0 on success
std::string putenv_arg = name + "=";
char* buf = (char*)std::malloc(putenv_arg.size() + 1);
std::memcpy(buf, putenv_arg.c_str(), putenv_arg.size() + 1);
return putenv(buf) == 0; // returns 0 on success. Potentially leaks, but it is the way putenv() behaves.
#endif
}
+5 -3
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
@@ -38,6 +38,7 @@
#elif defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
#include <cstring> // for string.h
#include <string.h> // strerror_s
#include "win32_tools.h"
#else
#include <cstring> // std::strerror
#endif
@@ -108,11 +109,12 @@ inline std::string errno_string(int errno_value)
}
#elif defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
char msg_buf[128] = {0}; // MS docs don't say exactly, but it's somewhere in 80-100 range.
if (strerror_s(msg_buf, 128, errno_value) != 0) { // always 0-terminated
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);
msg = buf;
}
msg = hz::win32_utf16_to_utf8_string(msg_buf);
#else // win32 and non-gnu/posix systems.
// win32 has thread-safe strerror().
+1 -1
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
+4 -1
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
@@ -27,6 +27,9 @@
#include "i18n.h" // HZ__
#include "string_algo.h" // string_replace
#ifdef _WIN32
#include "win32_tools.h"
#endif
namespace hz {
+7 -10
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
@@ -616,12 +616,9 @@ inline bool File::get_size(file_size_t& put_here, bool use_read)
}
const std::size_t buf_size = 32*1024; // 32K block devices will be happy
char buf[buf_size];
char buf[buf_size] = {0};
// read until the end
while (std::fread(buf, buf_size, 1, f) == 1) {
// nothing
}
(void)std::fread(buf, buf_size, 1, f);
if (std::ferror(f)) {
set_error(HZ__("Unable to read file \"/path1/\": /errno/."), errno, this->get_path());
@@ -770,7 +767,7 @@ inline bool File::copy(const std::string& to)
std::fclose(fsrc);
std::fclose(fdest);
#ifdef _WIN32
_wunlink(FsPath(to).get_utf16());
(void)_wunlink(FsPath(to).get_utf16());
#else
unlink(to.c_str());
#endif
@@ -781,7 +778,7 @@ inline bool File::copy(const std::string& to)
if (std::fclose(fsrc) == -1) {
std::fclose(fdest);
#ifdef _WIN32
_wunlink(FsPath(to).get_utf16());
(void)_wunlink(FsPath(to).get_utf16());
#else
unlink(to.c_str());
#endif
@@ -793,7 +790,7 @@ inline bool File::copy(const std::string& to)
if (std::fclose(fdest) == -1) { // the OS may delay writing until this point (or even further).
#ifdef _WIN32
_wunlink(FsPath(to).get_utf16());
(void)_wunlink(FsPath(to).get_utf16());
#else
unlink(to.c_str());
#endif
@@ -806,7 +803,7 @@ inline bool File::copy(const std::string& to)
// copy permissions. don't check for errors here - they are harmless.
if (stat_result == 0) {
#ifdef _WIN32
_wchmod(FsPath(to).get_utf16(), st.st_mode & (_S_IREAD | _S_IWRITE)); // it won't accept anything else.
(void)_wchmod(FsPath(to).get_utf16(), st.st_mode & (_S_IREAD | _S_IWRITE)); // it won't accept anything else.
#else
chmod(to.c_str(), st.st_mode & 07777); // don't transfer unneeded stuff (like "is directory").
#endif
+57 -6
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
@@ -24,7 +24,7 @@
#ifdef _WIN32
#include <io.h> // _waccess*(), _wstat(), _wunlink(), _wrmdir(), _wmkdir()
#include <utime.h> // _wutime()
#include <sys/utime.h> // _wutime()
#else
#include <cstddef> // std::size_t
#include <unistd.h> // access(), stat(), unlink(), readlink()
@@ -166,7 +166,7 @@ class FsPath : public FsPathHolder, public FsErrorHolder {
/// mkdir() mode type.
#ifdef _WIN32
typedef _mode_t mode_type; // they have some kind of unhealthy love for leading underscores.
typedef int mode_type;
#else
typedef mode_t mode_type;
#endif
@@ -209,6 +209,9 @@ class FsPath : public FsPathHolder, public FsErrorHolder {
/// The current object is also modified.
inline FsPath& compress();
/// Make the path absolute (if it's not already) by prepending \c base_path.
inline FsPath& make_absolute(const std::string& base_path);
/// Get the path truncated by 1 level, e.g. /usr/local/ -> /usr.
inline std::string get_dirname() const;
@@ -223,9 +226,18 @@ class FsPath : public FsPathHolder, public FsErrorHolder {
/// Check if the path corresponds to root (drive / share in win32).
inline bool is_root() const;
/// Get an extension of the last component.
/// Get an extension of the last component, e.g. /local/archive.tar.gz -> gz
inline std::string get_extension() const;
/// Get a full extension of the last component, e.g. /local/archive.tar.gz -> tar.gz
inline std::string get_full_extension() const;
/// Get the last component without extension, e.g. /local/archive.tar.gz -> archive.tar
inline std::string get_noext_basename() const;
/// Get the last component without extension, e.g. /local/archive.tar.gz -> archive
inline std::string get_noext_min_basename() const;
/// Check if the path is absolute (only for native paths). returns 0 if it's not.
/// the returned value is a position past the root component (e.g. 3 for C:\\temp).
inline std::string::size_type is_absolute() const;
@@ -373,6 +385,16 @@ inline FsPath& FsPath::compress()
FsPath& FsPath::make_absolute(const std::string& base_path)
{
if (!is_absolute()) {
set_path(FsPath(base_path).append(get_path()).get_path());
}
return compress();
}
inline std::string FsPath::get_dirname() const
{
return path_get_dirname(this->get_path());
@@ -413,6 +435,35 @@ inline std::string FsPath::get_extension() const
inline std::string FsPath::get_full_extension() const
{
std::string base = get_basename();
std::string::size_type pos = base.find('.');
if (pos != std::string::npos)
return base.substr(pos + 1);
return std::string();
}
std::string FsPath::get_noext_basename() const
{
std::string base = get_basename();
std::string::size_type pos = base.rfind('.');
return base.substr(0, pos);
}
std::string FsPath::get_noext_min_basename() const
{
std::string base = get_basename();
std::string::size_type pos = base.find('.');
return base.substr(0, pos);
}
inline std::string::size_type FsPath::is_absolute() const
{
return path_is_absolute(this->get_path());
@@ -544,9 +595,9 @@ inline bool FsPath::exists()
}
#if defined HAVE_WIN_SE_FUNCS && HAVE_WIN_SE_FUNCS
if (_waccess_s(this->get_utf16(), 00) == -1) // msvc uses integers instead (F_OK == 00 anyway).
if (_waccess_s(this->get_utf16(), 00) != 0) // msvc uses integers instead (F_OK == 00 anyway).
#elif defined _WIN32
if (_waccess(this->get_utf16(), 00) == -1) // msvc uses integers instead (F_OK == 00 anyway).
if (_waccess(this->get_utf16(), 00) != 0) // msvc uses integers instead (F_OK == 00 anyway).
#else
if (access(this->c_str(), F_OK) == -1)
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
+7 -7
View File
@@ -19,6 +19,7 @@
#ifdef _WIN32
#include <direct.h> // _wgetcwd, _wchdir
#include <string.h> // free
#else
#include <unistd.h> // getcwd, chdir
#endif
@@ -132,16 +133,15 @@ inline std::string get_current_dir()
std::string dir;
#ifdef _WIN32
std::size_t buf_size = MAX_PATH;
wchar_t* buf = new wchar_t[buf_size]; // not sure if it's really max, so increase it on demand
while (_wgetcwd(buf, static_cast<int>(buf_size)) == 0) {
delete[] buf;
buf = new wchar_t[buf_size *= 2];
wchar_t* buf = 0;
if (!(buf = _wgetcwd(NULL, 0))) { // allocates buf with malloc()
return std::string(); // error
}
dir = hz::win32_utf16_to_utf8_string(buf);
free(buf);
#else
std::size_t buf_size = 1024;
char* buf = new char[buf_size];
@@ -152,9 +152,9 @@ inline std::string get_current_dir()
}
dir = buf;
#endif
delete[] buf;
#endif
return dir;
}
+8 -1
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
@@ -345,6 +345,13 @@ HZ library internal implementation helpers.
#endif
#if !defined DISABLE_STRTOF && defined _MSC_VER
#define DISABLE_STRTOF 1
#endif
#if !defined DISABLE_STRTOLD && defined _MSC_VER
#define DISABLE_STRTOLD 1
#endif
+4 -4
View File
@@ -1,8 +1,8 @@
/**************************************************************************
Copyright:
(C) 1999 - 2010 Beman Dawes
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_boost_1_0.txt file
Copyright:
(C) 1999 - 2010 Beman Dawes
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See BOOST_LICENSE_1_0.txt file
***************************************************************************/
/// \file
/// \author Dave Abrahams
+1 -1
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
+1 -1
View File
@@ -2,7 +2,7 @@
Copyright:
(C) 1998 - 2010 Greg Colvin and Beman Dawes
(C) 2001 - 2010 Peter Dimov
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_boost_1_0.txt file
***************************************************************************/
/// \file
+114 -13
View File
@@ -112,6 +112,45 @@ void string_split(const std::string& str, const std::string& delimiter,
}
/// Split a string into components by any of the characters (delimiters), appending the
/// components (without delimiters) to container "append_here".
/// If skip_empty is true, then empty components will be omitted.
/// If "limit" is more than 0, only put a maximum of "limit" number of
/// elements into vector, with the last one containing the rest of the string.
template<class Container> inline
void string_split_by_chars(const std::string& str, const std::string& delimiter_chars,
Container& append_here, bool skip_empty = false, typename Container::difference_type limit = 0)
{
std::string::size_type curr = 0, last = 0;
std::string::size_type end = str.size();
typename Container::difference_type num = 0; // number inserted
while (true) {
if (last >= end) { // last is past the end
if (!skip_empty) // no need to check num here
append_here.push_back(std::string());
break;
}
curr = str.find_first_of(delimiter_chars, last);
if (!skip_empty || (curr != last)) {
if (++num == limit) {
append_here.push_back(str.substr(last, std::string::npos));
break;
} else {
append_here.push_back(str.substr(last, (curr == std::string::npos ? curr : (curr - last))));
}
}
if (curr == std::string::npos)
break;
last = curr + 1;
}
}
// --------------------------------------------- Join
@@ -424,7 +463,7 @@ inline std::string::size_type string_replace(std::string& s,
/// Replace from with to inside s, not modifying s, returning the changed string. char version.
inline std::string string_replace_copy(const std::string& s,
char from, char to, int max_replacements = -1)
char from, char to, int max_replacements = -1)
{
std::string ret(s);
string_replace(ret, from, to);
@@ -639,24 +678,65 @@ std::string string_replace_array_copy(const std::string& s,
// --------------------------------------------- Utility
// --------------------------------------------- Matching
/// Auto-detect and convert mac/dos/unix newline formats in s (modifying s) to unix format.
/// Returns number of newline replacements made.
inline std::string::size_type string_any_to_unix(std::string& s)
/// Check whether a string begins with another string
inline bool string_begins_with(const std::string& str, const std::string& substr)
{
std::string::size_type n = hz::string_replace(s, "\r\n", "\n"); // dos
n += hz::string_replace(s, '\r', '\n'); // mac
return n;
if (str.length() >= substr.length()) {
return (str.compare(0, substr.length(), substr) == 0);
}
return false;
}
/// Replace from_chars[0] with to_chars[0], from_chars[1] with to_chars[1], etc... in s,
/// not modifying s, returning the changed string.
/// from_chars.size() must be equal to to_chars.size().
/// Note: This is a multi-pass algorithm (there are from_chars.size() iterations).
/// Check whether a string begins with a character
inline bool string_begins_with(const std::string& str, char ch)
{
return !str.empty() && str[0] == ch;
}
/// Check whether a string ends with another string
inline bool string_ends_with(const std::string& str, const std::string& substr)
{
if (str.length() >= substr.length()) {
return (str.compare(str.length() - substr.length(), substr.length(), substr) == 0);
}
return false;
}
/// Check whether a string ends with a character
inline bool string_ends_with(const std::string& str, char ch)
{
return !str.empty() && str[str.size() - 1] == ch;
}
// --------------------------------------------- Utility
/// Auto-detect and convert mac/dos/unix newline formats in s (modifying s) to unix format.
/// Returns true if \c s was changed.
inline bool string_any_to_unix(std::string& s)
{
std::string::size_type n = hz::string_replace(s, "\r\n", "\n"); // dos
n += hz::string_replace(s, '\r', '\n'); // mac
return bool(n);
}
/// Auto-detect and convert mac/dos/unix newline formats in s to unix format.
/// Returns the result string.
inline std::string string_any_to_unix_copy(const std::string& s)
{
std::string ret(s);
@@ -665,6 +745,27 @@ inline std::string string_any_to_unix_copy(const std::string& s)
}
/// Auto-detect and convert mac/dos/unix newline formats in s (modifying s) to dos format.
/// Returns true if \c s was changed.
inline bool string_any_to_dos(std::string& s)
{
bool changed = string_any_to_unix(s);
std::string::size_type n = hz::string_replace(s, "\n", "\r\n"); // dos
return bool(n) || changed; // may not really work
}
/// Auto-detect and convert mac/dos/unix newline formats in s to dos format.
/// Returns the result string.
inline std::string string_any_to_dos_copy(const std::string& s)
{
std::string ret(s);
string_any_to_dos(ret);
return ret;
}
/// Convert s to lowercase (modifying s). Return size of the string.
inline std::string::size_type string_to_lower(std::string& s)
@@ -693,7 +794,7 @@ inline std::string::size_type string_to_upper(std::string& s)
{
const std::string::size_type len = s.size();
for(std::string::size_type i = 0; i != len; ++i) {
s[i] = static_cast<char>(std::tolower(s[i]));
s[i] = static_cast<char>(std::toupper(s[i]));
}
return len;
}
+34 -4
View File
@@ -25,7 +25,7 @@
#include "type_properties.h" // type_is_*
#include "type_categories.h" // type_check_category
#include "static_assert.h" // HZ_STATIC_ASSERT
// #include "static_assert.h" // HZ_STATIC_ASSERT
#include "ascii.h" // ascii_*
@@ -57,12 +57,22 @@ namespace hz {
bool string_is_numeric(const std::string& s, T& number, bool strict = true);
/// A convenience string_is_numeric wrapper.
/// Note that in strict mode, T() is returned for invalid values.
template<typename T> inline
T string_to_number(const std::string& s, bool strict, int base_or_boolalpha);
/// Short version with default base. (Needed because default base is different for bool and int).
template<typename T> inline
T string_to_number(const std::string& s, bool strict = true);
/// Convert numeric value to string. alpha_or_base_or_precision means:
/// for bool, 0 means 1/0, 1 means true/false;
/// for int family (including char), it's the base to format in (8, 10, 16 are definitely supported);
/// for float family, it controls the number of digits after comma.
template<typename T> inline
std::string number_to_string(T number, int alpha_or_base_or_precision);
std::string number_to_string(T number, int alpha_or_base_or_precision, bool fixed_prec = false);
/// Short version with default base / precision.
template<typename T> inline
@@ -82,6 +92,26 @@ namespace hz {
template<typename T> inline
T string_to_number(const std::string& s, bool strict, int base_or_boolalpha)
{
T value = T();
hz::string_is_numeric(s, value, strict, base_or_boolalpha);
return value;
}
template<typename T> inline
T string_to_number(const std::string& s, bool strict)
{
T value = T();
hz::string_is_numeric(s, value, strict);
return value;
}
// Definition of the one without base parameter.
template<typename T> inline
bool string_is_numeric(const std::string& s, T& number, bool strict)
@@ -290,9 +320,9 @@ namespace internal {
// public function with 2 parameters
template<typename T> inline
std::string number_to_string(T number, int boolalpha_or_base_or_precision)
std::string number_to_string(T number, int boolalpha_or_base_or_precision, bool fixed_prec)
{
return internal::number_to_string_impl<T>::func(number, boolalpha_or_base_or_precision, true);
return internal::number_to_string_impl<T>::func(number, boolalpha_or_base_or_precision, fixed_prec);
}
+1 -1
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file
+1 -1
View File
@@ -1,6 +1,6 @@
/**************************************************************************
Copyright:
(C) 2008 - 2012 Alexander Shaduri <ashaduri 'at' gmail.com>
(C) 2008 - 2013 Alexander Shaduri <ashaduri 'at' gmail.com>
License: See LICENSE_zlib.txt file
***************************************************************************/
/// \file