utils: cleanup whitespace

This commit is contained in:
Dirk-Jan C. Binnema
2021-03-16 17:07:39 +02:00
parent 725826231f
commit 15aca5e396
3 changed files with 285 additions and 269 deletions

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2017 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2017-2021 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This library is free software; you can redistribute it and/or ** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public License ** modify it under the terms of the GNU Lesser General Public License
@ -89,7 +89,7 @@ gx_utf8_flatten (const gchar *str, gssize len)
uc = g_utf8_get_char (cur); uc = g_utf8_get_char (cur);
if (g_unichar_combining_class (uc) != 0) if (g_unichar_combining_class (uc) != 0)
continue; continue;
g_string_append_unichar (gstr, unichar_tolower(uc)); g_string_append_unichar (gstr, unichar_tolower(uc));
} }
@ -104,49 +104,52 @@ gx_utf8_flatten (const gchar *str, gssize len)
std::string // gx_utf8_flatten std::string // gx_utf8_flatten
Mu::utf8_flatten (const char *str) Mu::utf8_flatten (const char *str)
{ {
if (!str) if (!str)
return {}; return {};
// the pure-ascii case // the pure-ascii case
if (g_str_is_ascii(str)) { if (g_str_is_ascii(str)) {
auto l = g_ascii_strdown (str, -1); auto l = g_ascii_strdown (str, -1);
std::string s{l}; std::string s{l};
g_free (l); g_free (l);
return s; return s;
} }
// seems we need the big guns // seems we need the big guns
char *flat = gx_utf8_flatten (str, -1); char *flat = gx_utf8_flatten (str, -1);
if (!flat) if (!flat)
return {}; return {};
std::string s{flat}; std::string s{flat};
g_free (flat); g_free (flat);
return s; return s;
} }
std::string std::string
Mu::utf8_clean (const std::string& dirty) Mu::utf8_clean (const std::string& dirty)
{ {
GString *gstr = g_string_sized_new (dirty.length()); GString *gstr = g_string_sized_new (dirty.length());
for (auto cur = dirty.c_str(); cur && *cur; cur = g_utf8_next_char (cur)) { for (auto cur = dirty.c_str(); cur && *cur; cur = g_utf8_next_char (cur)) {
const gunichar uc = g_utf8_get_char (cur); const gunichar uc = g_utf8_get_char (cur);
if (g_unichar_iscntrl (uc)) if (g_unichar_iscntrl (uc))
g_string_append_c (gstr, ' '); g_string_append_c (gstr, ' ');
else else
g_string_append_unichar (gstr, uc); g_string_append_unichar (gstr, uc);
} }
std::string clean(gstr->str, gstr->len); std::string clean(gstr->str, gstr->len);
g_string_free (gstr, TRUE); g_string_free (gstr, TRUE);
clean.erase (0, clean.find_first_not_of(" "));
clean.erase (clean.find_last_not_of(" ") + 1); // remove trailing space
return clean;
}
clean.erase (0, clean.find_first_not_of(" "));
clean.erase (clean.find_last_not_of(" ") + 1); // remove trailing space
return clean;
std::string std::string
Mu::remove_ctrl (const std::string& str) Mu::remove_ctrl (const std::string& str)
{ {
@ -165,17 +168,18 @@ Mu::remove_ctrl (const std::string& str)
return result; return result;
} }
std::vector<std::string> std::vector<std::string>
Mu::split (const std::string& str, const std::string& sepa) Mu::split (const std::string& str, const std::string& sepa)
{ {
char **parts = g_strsplit(str.c_str(), sepa.c_str(), -1); char **parts = g_strsplit(str.c_str(), sepa.c_str(), -1);
std::vector<std::string> vec; std::vector<std::string> vec;
for (auto part = parts; part && *part; ++part) for (auto part = parts; part && *part; ++part)
vec.push_back (*part); vec.push_back (*part);
g_strfreev(parts); g_strfreev(parts);
return vec; return vec;
} }
std::string std::string
@ -197,13 +201,13 @@ Mu::quote (const std::string& str)
std::string std::string
Mu::format (const char *frm, ...) Mu::format (const char *frm, ...)
{ {
va_list args; va_list args;
va_start (args, frm); va_start (args, frm);
auto str = format(frm, args); auto str = format(frm, args);
va_end (args); va_end (args);
return str; return str;
} }
std::string std::string
@ -216,10 +220,10 @@ Mu::format (const char *frm, va_list args)
return {}; return {};
} }
std::string str{s}; std::string str{s};
g_free (s); g_free (s);
return str; return str;
} }
@ -232,84 +236,84 @@ static_assert(sizeof(InternalDateMax) == 10 + 1, "invalid");
static std::string static std::string
date_boundary (bool is_first) date_boundary (bool is_first)
{ {
return is_first ? InternalDateMin : InternalDateMax; return is_first ? InternalDateMin : InternalDateMax;
} }
std::string std::string
Mu::date_to_time_t_string (int64_t t) Mu::date_to_time_t_string (int64_t t)
{ {
char buf[sizeof(InternalDateMax)]; char buf[sizeof(InternalDateMax)];
g_snprintf (buf, sizeof(buf), InternalDateFormat, t); g_snprintf (buf, sizeof(buf), InternalDateFormat, t);
return buf; return buf;
} }
static std::string static std::string
delta_ymwdhMs (const std::string& expr) delta_ymwdhMs (const std::string& expr)
{ {
char *endptr; char *endptr;
auto num = strtol (expr.c_str(), &endptr, 10); auto num = strtol (expr.c_str(), &endptr, 10);
if (num <= 0 || num > 9999 || !endptr || !*endptr) if (num <= 0 || num > 9999 || !endptr || !*endptr)
return date_boundary (true); return date_boundary (true);
int years, months, weeks, days, hours, minutes, seconds; int years, months, weeks, days, hours, minutes, seconds;
years = months = weeks = days = hours = minutes = seconds = 0; years = months = weeks = days = hours = minutes = seconds = 0;
switch (endptr[0]) { switch (endptr[0]) {
case 's': seconds = num; break; case 's': seconds = num; break;
case 'M': minutes = num; break; case 'M': minutes = num; break;
case 'h': hours = num; break; case 'h': hours = num; break;
case 'd': days = num; break; case 'd': days = num; break;
case 'w': weeks = num; break; case 'w': weeks = num; break;
case 'm': months = num; break; case 'm': months = num; break;
case 'y': years = num; break; case 'y': years = num; break;
default: default:
return date_boundary (true); return date_boundary (true);
} }
GDateTime *then, *now = g_date_time_new_now_local (); GDateTime *then, *now = g_date_time_new_now_local ();
if (weeks != 0) if (weeks != 0)
then = g_date_time_add_weeks (now, -weeks); then = g_date_time_add_weeks (now, -weeks);
else else
then = g_date_time_add_full (now, -years, -months,-days, then = g_date_time_add_full (now, -years, -months,-days,
-hours, -minutes, -seconds); -hours, -minutes, -seconds);
time_t t = MAX (0, (gint64)g_date_time_to_unix (then)); time_t t = MAX (0, (gint64)g_date_time_to_unix (then));
g_date_time_unref (then); g_date_time_unref (then);
g_date_time_unref (now); g_date_time_unref (now);
return date_to_time_t_string (t); return date_to_time_t_string (t);
} }
static std::string static std::string
special_date (const std::string& d, bool is_first) special_date (const std::string& d, bool is_first)
{ {
if (d == "now") if (d == "now")
return date_to_time_t_string (time(NULL)); return date_to_time_t_string (time(NULL));
else if (d == "today") { else if (d == "today") {
GDateTime *dt, *midnight; GDateTime *dt, *midnight;
dt = g_date_time_new_now_local (); dt = g_date_time_new_now_local ();
if (!is_first) { if (!is_first) {
GDateTime *tmp = dt; GDateTime *tmp = dt;
dt = g_date_time_add_days (dt, 1); dt = g_date_time_add_days (dt, 1);
g_date_time_unref (tmp); g_date_time_unref (tmp);
} }
midnight = g_date_time_add_full (dt, 0, 0, 0, midnight = g_date_time_add_full (dt, 0, 0, 0,
-g_date_time_get_hour(dt), -g_date_time_get_hour(dt),
-g_date_time_get_minute (dt), -g_date_time_get_minute (dt),
-g_date_time_get_second (dt)); -g_date_time_get_second (dt));
time_t t = MAX(0, (gint64)g_date_time_to_unix (midnight)); time_t t = MAX(0, (gint64)g_date_time_to_unix (midnight));
g_date_time_unref (dt); g_date_time_unref (dt);
g_date_time_unref (midnight); g_date_time_unref (midnight);
return date_to_time_t_string ((time_t)t); return date_to_time_t_string ((time_t)t);
} else } else
return date_boundary (is_first); return date_boundary (is_first);
} }
// if a date has a month day greater than the number of days in that month, // if a date has a month day greater than the number of days in that month,
@ -317,87 +321,87 @@ special_date (const std::string& d, bool is_first)
static void static void
fixup_month (struct tm *tbuf) fixup_month (struct tm *tbuf)
{ {
decltype(tbuf->tm_mday) max_days; decltype(tbuf->tm_mday) max_days;
const auto month = tbuf->tm_mon + 1; const auto month = tbuf->tm_mon + 1;
const auto year = tbuf->tm_year + 1900; const auto year = tbuf->tm_year + 1900;
switch (month) { switch (month) {
case 2: case 2:
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
max_days = 29; max_days = 29;
else else
max_days = 28; max_days = 28;
break; break;
case 4: case 4:
case 6: case 6:
case 9: case 9:
case 11: case 11:
max_days = 30; max_days = 30;
break; break;
default: default:
max_days = 31; max_days = 31;
break; break;
} }
if (tbuf->tm_mday > max_days) { if (tbuf->tm_mday > max_days) {
tbuf->tm_mday = max_days; tbuf->tm_mday = max_days;
tbuf->tm_hour = 23; tbuf->tm_hour = 23;
tbuf->tm_min = 59; tbuf->tm_min = 59;
tbuf->tm_sec = 59; tbuf->tm_sec = 59;
} }
} }
std::string std::string
Mu::date_to_time_t_string (const std::string& dstr, bool is_first) Mu::date_to_time_t_string (const std::string& dstr, bool is_first)
{ {
gint64 t; gint64 t;
struct tm tbuf; struct tm tbuf;
GDateTime *dtime; GDateTime *dtime;
/* one-sided dates */ /* one-sided dates */
if (dstr.empty()) if (dstr.empty())
return date_boundary (is_first); return date_boundary (is_first);
else if (dstr == "today" || dstr == "now") else if (dstr == "today" || dstr == "now")
return special_date (dstr, is_first); return special_date (dstr, is_first);
else if (dstr.find_first_of("ymdwhMs") != std::string::npos) else if (dstr.find_first_of("ymdwhMs") != std::string::npos)
return delta_ymwdhMs (dstr); return delta_ymwdhMs (dstr);
constexpr char UserDateMin[] = "19700101000000"; constexpr char UserDateMin[] = "19700101000000";
constexpr char UserDateMax[] = "29991231235959"; constexpr char UserDateMax[] = "29991231235959";
std::string date (is_first ? UserDateMin : UserDateMax); std::string date (is_first ? UserDateMin : UserDateMax);
std::copy_if (dstr.begin(), dstr.end(), date.begin(),[](auto c){return isdigit(c);}); std::copy_if (dstr.begin(), dstr.end(), date.begin(),[](auto c){return isdigit(c);});
memset (&tbuf, 0, sizeof tbuf); memset (&tbuf, 0, sizeof tbuf);
if (!strptime (date.c_str(), "%Y%m%d%H%M%S", &tbuf) && if (!strptime (date.c_str(), "%Y%m%d%H%M%S", &tbuf) &&
!strptime (date.c_str(), "%Y%m%d%H%M", &tbuf) && !strptime (date.c_str(), "%Y%m%d%H%M", &tbuf) &&
!strptime (date.c_str(), "%Y%m%d", &tbuf) && !strptime (date.c_str(), "%Y%m%d", &tbuf) &&
!strptime (date.c_str(), "%Y%m", &tbuf) && !strptime (date.c_str(), "%Y%m", &tbuf) &&
!strptime (date.c_str(), "%Y", &tbuf)) !strptime (date.c_str(), "%Y", &tbuf))
return date_boundary (is_first); return date_boundary (is_first);
fixup_month(&tbuf); fixup_month(&tbuf);
dtime = g_date_time_new_local (tbuf.tm_year + 1900, dtime = g_date_time_new_local (tbuf.tm_year + 1900,
tbuf.tm_mon + 1, tbuf.tm_mon + 1,
tbuf.tm_mday, tbuf.tm_mday,
tbuf.tm_hour, tbuf.tm_hour,
tbuf.tm_min, tbuf.tm_min,
tbuf.tm_sec); tbuf.tm_sec);
if (!dtime) { if (!dtime) {
g_warning ("invalid %s date '%s'", g_warning ("invalid %s date '%s'",
is_first ? "lower" : "upper", date.c_str()); is_first ? "lower" : "upper", date.c_str());
return date_boundary (is_first); return date_boundary (is_first);
} }
t = g_date_time_to_unix (dtime); t = g_date_time_to_unix (dtime);
g_date_time_unref (dtime); g_date_time_unref (dtime);
if (t < 0 || t > 9999999999) if (t < 0 || t > 9999999999)
return date_boundary (is_first); return date_boundary (is_first);
else else
return date_to_time_t_string (t); return date_to_time_t_string (t);
} }
constexpr const auto SizeFormat = "%010" G_GINT64_FORMAT; constexpr const auto SizeFormat = "%010" G_GINT64_FORMAT;
@ -410,57 +414,57 @@ static_assert(sizeof(SizeMax) == 10 + 1, "invalid");
static std::string static std::string
size_boundary (bool is_first) size_boundary (bool is_first)
{ {
return is_first ? SizeMin : SizeMax; return is_first ? SizeMin : SizeMax;
} }
std::string std::string
Mu::size_to_string (int64_t size) Mu::size_to_string (int64_t size)
{ {
char buf[sizeof(SizeMax)]; char buf[sizeof(SizeMax)];
g_snprintf (buf, sizeof(buf), SizeFormat, size); g_snprintf (buf, sizeof(buf), SizeFormat, size);
return buf; return buf;
} }
std::string std::string
Mu::size_to_string (const std::string& val, bool is_first) Mu::size_to_string (const std::string& val, bool is_first)
{ {
std::string str; std::string str;
GRegex *rx; GRegex *rx;
GMatchInfo *minfo; GMatchInfo *minfo;
/* one-sided ranges */ /* one-sided ranges */
if (val.empty()) if (val.empty())
return size_boundary (is_first); return size_boundary (is_first);
rx = g_regex_new ("(\\d+)(b|k|kb|m|mb|g|gb)?", rx = g_regex_new ("(\\d+)(b|k|kb|m|mb|g|gb)?",
G_REGEX_CASELESS, (GRegexMatchFlags)0, NULL); G_REGEX_CASELESS, (GRegexMatchFlags)0, NULL);
minfo = NULL; minfo = NULL;
if (g_regex_match (rx, val.c_str(), (GRegexMatchFlags)0, &minfo)) { if (g_regex_match (rx, val.c_str(), (GRegexMatchFlags)0, &minfo)) {
gint64 size; gint64 size;
char *s; char *s;
s = g_match_info_fetch (minfo, 1); s = g_match_info_fetch (minfo, 1);
size = atoll (s); size = atoll (s);
g_free (s); g_free (s);
s = g_match_info_fetch (minfo, 2); s = g_match_info_fetch (minfo, 2);
switch (s ? g_ascii_tolower(s[0]) : 0) { switch (s ? g_ascii_tolower(s[0]) : 0) {
case 'k': size *= 1024; break; case 'k': size *= 1024; break;
case 'm': size *= (1024 * 1024); break; case 'm': size *= (1024 * 1024); break;
case 'g': size *= (1024 * 1024 * 1024); break; case 'g': size *= (1024 * 1024 * 1024); break;
default: break; default: break;
} }
g_free (s); g_free (s);
str = size_to_string (size); str = size_to_string (size);
} else } else
str = size_boundary (is_first); str = size_boundary (is_first);
g_regex_unref (rx); g_regex_unref (rx);
g_match_info_unref (minfo); g_match_info_unref (minfo);
return str; return str;
} }

View File

@ -1,5 +1,5 @@
/* /*
** Copyright (C) 2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ** Copyright (C) 2020-2021 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** **
** This library is free software; you can redistribute it and/or ** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public License ** modify it under the terms of the GNU Lesser General Public License
@ -43,8 +43,6 @@ using StringVec = std::vector<std::string>;
std::string utf8_flatten (const char *str); std::string utf8_flatten (const char *str);
inline std::string utf8_flatten (const std::string& s) { return utf8_flatten(s.c_str()); } inline std::string utf8_flatten (const std::string& s) { return utf8_flatten(s.c_str()); }
/** /**
* Replace all control characters with spaces, and remove leading and trailing space. * Replace all control characters with spaces, and remove leading and trailing space.
* *
@ -55,6 +53,19 @@ inline std::string utf8_flatten (const std::string& s) { return utf8_flatten(s.c
std::string utf8_clean (const std::string& dirty); std::string utf8_clean (const std::string& dirty);
/**
* Remove ctrl characters, replacing them with ' '; subsequent
* ctrl characters are replaced by a single ' '
*
* @param str a string
*
* @return the string without control characters
*/
std::string remove_ctrl (const std::string& str);
/** /**
* Split a string in parts * Split a string in parts
* *
@ -64,7 +75,7 @@ std::string utf8_clean (const std::string& dirty);
* @return the parts. * @return the parts.
*/ */
std::vector<std::string> split (const std::string& str, std::vector<std::string> split (const std::string& str,
const std::string& sepa); const std::string& sepa);
/** /**
* Quote & escape a string for " and \ * Quote & escape a string for " and \
@ -241,69 +252,69 @@ private:
*/ */
#define MU_XAPIAN_CATCH_BLOCK \ #define MU_XAPIAN_CATCH_BLOCK \
catch (const Xapian::Error &xerr) { \ catch (const Xapian::Error &xerr) { \
g_critical ("%s: xapian error '%s'", \ g_critical ("%s: xapian error '%s'", \
__func__, xerr.get_msg().c_str()); \ __func__, xerr.get_msg().c_str()); \
} catch (const std::runtime_error& re) { \ } catch (const std::runtime_error& re) { \
g_critical ("%s: error: %s", __func__, re.what()); \ g_critical ("%s: error: %s", __func__, re.what()); \
} catch (...) { \ } catch (...) { \
g_critical ("%s: caught exception", __func__); \ g_critical ("%s: caught exception", __func__); \
} }
#define MU_XAPIAN_CATCH_BLOCK_G_ERROR(GE,E) \ #define MU_XAPIAN_CATCH_BLOCK_G_ERROR(GE,E) \
catch (const Xapian::DatabaseLockError &xerr) { \ catch (const Xapian::DatabaseLockError &xerr) { \
mu_util_g_set_error ((GE), \ mu_util_g_set_error ((GE), \
MU_ERROR_XAPIAN_CANNOT_GET_WRITELOCK, \ MU_ERROR_XAPIAN_CANNOT_GET_WRITELOCK, \
"%s: xapian error '%s'", \ "%s: xapian error '%s'", \
__func__, xerr.get_msg().c_str()); \ __func__, xerr.get_msg().c_str()); \
} catch (const Xapian::DatabaseError &xerr) { \ } catch (const Xapian::DatabaseError &xerr) { \
mu_util_g_set_error ((GE),MU_ERROR_XAPIAN, \ mu_util_g_set_error ((GE),MU_ERROR_XAPIAN, \
"%s: xapian error '%s'", \ "%s: xapian error '%s'", \
__func__, xerr.get_msg().c_str()); \ __func__, xerr.get_msg().c_str()); \
} catch (const Xapian::Error &xerr) { \ } catch (const Xapian::Error &xerr) { \
mu_util_g_set_error ((GE),(E), \ mu_util_g_set_error ((GE),(E), \
"%s: xapian error '%s'", \ "%s: xapian error '%s'", \
__func__, xerr.get_msg().c_str()); \ __func__, xerr.get_msg().c_str()); \
} catch (const std::runtime_error& ex) { \ } catch (const std::runtime_error& ex) { \
mu_util_g_set_error ((GE),(MU_ERROR_INTERNAL), \ mu_util_g_set_error ((GE),(MU_ERROR_INTERNAL), \
"%s: error: %s", __func__, ex.what()); \ "%s: error: %s", __func__, ex.what()); \
\ \
} catch (...) { \ } catch (...) { \
mu_util_g_set_error ((GE),(MU_ERROR_INTERNAL), \ mu_util_g_set_error ((GE),(MU_ERROR_INTERNAL), \
"%s: caught exception", __func__); \ "%s: caught exception", __func__); \
} }
#define MU_XAPIAN_CATCH_BLOCK_RETURN(R) \ #define MU_XAPIAN_CATCH_BLOCK_RETURN(R) \
catch (const Xapian::Error &xerr) { \ catch (const Xapian::Error &xerr) { \
g_critical ("%s: xapian error '%s'", \ g_critical ("%s: xapian error '%s'", \
__func__, xerr.get_msg().c_str()); \ __func__, xerr.get_msg().c_str()); \
return (R); \ return (R); \
} catch (const std::runtime_error& ex) { \ } catch (const std::runtime_error& ex) { \
g_critical("%s: error: %s", __func__, ex.what()); \ g_critical("%s: error: %s", __func__, ex.what()); \
return (R); \ return (R); \
} catch (...) { \ } catch (...) { \
g_critical ("%s: caught exception", __func__); \ g_critical ("%s: caught exception", __func__); \
return (R); \ return (R); \
} }
#define MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN(GE,E,R) \ #define MU_XAPIAN_CATCH_BLOCK_G_ERROR_RETURN(GE,E,R) \
catch (const Xapian::Error &xerr) { \ catch (const Xapian::Error &xerr) { \
mu_util_g_set_error ((GE),(E), \ mu_util_g_set_error ((GE),(E), \
"%s: xapian error '%s'", \ "%s: xapian error '%s'", \
__func__, xerr.get_msg().c_str()); \ __func__, xerr.get_msg().c_str()); \
return (R); \ return (R); \
} catch (const std::runtime_error& ex) { \ } catch (const std::runtime_error& ex) { \
mu_util_g_set_error ((GE),(MU_ERROR_INTERNAL), \ mu_util_g_set_error ((GE),(MU_ERROR_INTERNAL), \
"%s: error: %s", __func__, ex.what()); \ "%s: error: %s", __func__, ex.what()); \
return (R); \ return (R); \
} catch (...) { \ } catch (...) { \
if ((GE)&&!(*(GE))) \ if ((GE)&&!(*(GE))) \
mu_util_g_set_error ((GE), \ mu_util_g_set_error ((GE), \
(MU_ERROR_INTERNAL), \ (MU_ERROR_INTERNAL), \
"%s: caught exception", __func__); \ "%s: caught exception", __func__); \
return (R); \ return (R); \
} }

View File

@ -179,26 +179,26 @@ MU_ENABLE_BITOPS(Bits);
static void static void
test_define_bitmap() test_define_bitmap()
{ {
g_assert_cmpuint((guint)Bits::None,==,(guint)0); g_assert_cmpuint((guint)Bits::None,==,(guint)0);
g_assert_cmpuint((guint)Bits::Bit1,==,(guint)1); g_assert_cmpuint((guint)Bits::Bit1,==,(guint)1);
g_assert_cmpuint((guint)Bits::Bit2,==,(guint)2); g_assert_cmpuint((guint)Bits::Bit2,==,(guint)2);
g_assert_cmpuint((guint)(Bits::Bit1|Bits::Bit2),==,(guint)3); g_assert_cmpuint((guint)(Bits::Bit1|Bits::Bit2),==,(guint)3);
g_assert_cmpuint((guint)(Bits::Bit1&Bits::Bit2),==,(guint)0); g_assert_cmpuint((guint)(Bits::Bit1&Bits::Bit2),==,(guint)0);
g_assert_cmpuint((guint)(Bits::Bit1&(~Bits::Bit2)),==,(guint)1); g_assert_cmpuint((guint)(Bits::Bit1&(~Bits::Bit2)),==,(guint)1);
{ {
Bits b{Bits::Bit1}; Bits b{Bits::Bit1};
b|=Bits::Bit2; b|=Bits::Bit2;
g_assert_cmpuint((guint)b,==,(guint)3); g_assert_cmpuint((guint)b,==,(guint)3);
} }
{ {
Bits b{Bits::Bit1}; Bits b{Bits::Bit1};
b&=Bits::Bit1; b&=Bits::Bit1;
g_assert_cmpuint((guint)b,==,(guint)1); g_assert_cmpuint((guint)b,==,(guint)1);
} }
} }
@ -214,9 +214,10 @@ main (int argc, char *argv[])
g_test_add_func ("/utils/date-ymwdhMs", test_date_ymwdhMs); g_test_add_func ("/utils/date-ymwdhMs", test_date_ymwdhMs);
g_test_add_func ("/utils/size", test_size); g_test_add_func ("/utils/size", test_size);
g_test_add_func ("/utils/flatten", test_flatten); g_test_add_func ("/utils/flatten", test_flatten);
g_test_add_func ("/utils/remove-ctrl", test_remove_ctrl);
g_test_add_func ("/utils/clean", test_clean); g_test_add_func ("/utils/clean", test_clean);
g_test_add_func ("/utils/format", test_format); g_test_add_func ("/utils/format", test_format);
g_test_add_func ("/utils/define-bitmap", test_define_bitmap); g_test_add_func ("/utils/define-bitmap", test_define_bitmap);
return g_test_run (); return g_test_run ();
} }