25  static const char *
const ase_debug = [] {
 
   26    const char *
const d = 
getenv (
"ASE_DEBUG");
 
   64  struct timeval tv = { 0, };
 
   66  const char *
const newline = !message.
empty() && message.
data()[message.
size() - 1] == 
'\n' ? 
"" : 
"\n";
 
   67  using namespace AnsiColors;
 
   68  const std::string col = color (FG_CYAN, BOLD), reset = color (RESET);
 
   69  const std::string ul = cond ? color (UNDERLINE) : 
"", nl = cond ? color (UNDERLINE_OFF) : 
"";
 
   71  sout += 
string_format (
"%s%u.%06u ", col, tv.tv_sec, tv.tv_usec); 
 
   74  printerr (
"%s%s", sout, newline);
 
 
   90  using namespace AnsiColors;
 
   93    prefix = color (FG_YELLOW) + 
"warning:" + color (RESET) + 
" ";
 
   95    prefix = color (BG_RED, FG_WHITE, BOLD) + 
"error:" + color (RESET) + 
" ";
 
   97  if (!executable.
empty())
 
   99      size_t sep = executable.
find (
" ");
 
  100      if (sep != std::string::npos)
 
  101        executable = executable.
substr (0, sep);        
 
  102      sep = executable.
rfind (
"/");
 
  103      if (sep != std::string::npos)
 
  104        executable = executable.
substr (sep + 1);       
 
  105      if (!executable.
empty())
 
  106        prefix = executable + 
": " + prefix;
 
 
  113ase_gettext (
const String &untranslated)
 
  115  CString translated = untranslated;
 
  116  return translated.c_str(); 
 
  121now_strftime (
const String &format)
 
  124  char buffer[4096] = { 0, };
 
  142    if (word.
empty()) 
return true;
 
  145        warning (
"%s: invalid icon keyword: '%s'", __func__, word);
 
  152  if (!is.empty() && is.find (
',') == is.npos)
 
 
  159operator""_icon (
const char *key, 
size_t)
 
 
  173    warning (
"%s: invalid icon unicode: '%s'", __func__, unicode);
 
 
  181operator""_uc (
const char *key, 
size_t)
 
 
  192    warning (
"%s: invalid svg icon: %s…", __func__, svgdata.
substr (0, 40));
 
 
  210  ASE_UNUSED 
long nflags;
 
  211#ifdef HAVE_SYS_EVENTFD_H 
  213    fds[0] = eventfd (0 , EFD_CLOEXEC | EFD_NONBLOCK);
 
  218    err = pipe2 (fds, O_CLOEXEC | O_NONBLOCK);
 
  222      nflags = 
fcntl (fds[1], F_GETFL, 0);
 
  224      nflags = 
fcntl (fds[1], F_GETFD, 0);
 
  230      nflags = 
fcntl (fds[0], F_GETFL, 0);
 
  232      nflags = 
fcntl (fds[0], F_GETFD, 0);
 
 
  254  struct pollfd pfd = { 
inputfd(), POLLIN, 0 };
 
  257    presult = 
poll (&pfd, 1, -1);
 
  259  return pfd.revents != 0;
 
 
  266#ifdef HAVE_SYS_EVENTFD_H 
  268    err = eventfd_write (fds[0], 1);
 
  273    err = 
write (fds[1], &w, 1);
 
 
  283#ifdef HAVE_SYS_EVENTFD_H 
  286    err = eventfd_read (fds[0], &bytes8);
 
  291    err = 
read (fds[0], buffer, 
sizeof (buffer));
 
  292  while (err == 512 || (err < 0 && 
errno == 
EINTR));
 
 
  299#ifdef HAVE_SYS_EVENTFD_H 
  310CustomDataContainer::CustomDataEntry&
 
  311CustomDataContainer::custom_data_entry (VirtualBase *key)
 
  316  for (
auto &e : *custom_data_)
 
  319  custom_data_->push_back ({ .key = key, });
 
  320  return custom_data_->back();
 
  324CustomDataContainer::custom_data_get (VirtualBase *key)
 const 
  327    for (
auto &e : *custom_data_)
 
  335CustomDataContainer::custom_data_del (VirtualBase *key)
 
  338    return Aux::erase_first (*custom_data_, [key] (
auto &e) { 
return key == e.key; });
 
  340  static_assert (
sizeof (CustomDataContainer) == 
sizeof (
void*));
 
  344CustomDataContainer::custom_data_destroy()
 
  347  while (!custom_data_->empty())
 
  351      custom_data_->pop_back();
 
  356CustomDataContainer::~CustomDataContainer()
 
  358  custom_data_destroy();
 
  372  TASSERT (uint16_swap_le_be (0x1234) == 0x3412);
 
  373  TASSERT (uint32_swap_le_be (0xe23456f8) == 0xf85634e2);
 
  374  TASSERT (uint64_swap_le_be (0xf2345678a1b2c3d4) == 0xd4c3b2a1785634f2);
 
  377  b = Aux::contains (fv, [] (
auto v) { 
return v == 9; }); 
TASSERT (b == 
false);
 
  378  b = Aux::contains (fv, [] (
auto v) { 
return v == 2; }); 
TASSERT (b == 
true);
 
  380  j = Aux::erase_all (fv, [] (
auto v) { 
return fabs (v) == 2; });
 
  382  j = Aux::erase_first (fv, [] (
auto v) { 
return fabs (v) == 1; });
 
bool opened()
Indicates whether eventfd has been opened.
 
void flush()
Clear pending wakeups.
 
int inputfd()
Returns the file descriptor for POLLIN.
 
bool pollin()
Checks whether events are pending.
 
int open()
Opens the eventfd and returns -errno.
 
void wakeup()
Wakeup polling end.
 
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
 
#define return_unless(cond,...)
Return silently if cond does not evaluate to true with return value ...
 
#define TEST_INTEGRITY(FUNC)
Register func as an integrity test.
 
size_t erase_all(C &container, const std::function< bool(typename C::value_type const &value)> &pred)
Erase all elements for which pred() is true in vector or list.
 
size_t erase_first(C &container, const std::function< bool(typename C::value_type const &value)> &pred)
Erase first element for which pred() is true in vector or list.
 
The Anklang C++ API namespace.
 
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
 
bool debug_key_enabled(const char *conditional)
Check if conditional is enabled by $ASE_DEBUG.
 
bool ase_fatal_warnings
Global boolean to cause the program to abort on warnings.
 
String string_join(const String &junctor, const StringS &strvec)
 
String diag_prefix(uint8 code)
Create prefix for warnings and errors.
 
bool string_is_canonified(const String &string, const String &valid_chars)
Check if string_canonify() would modify string.
 
uint8_t uint8
An 8-bit unsigned integer.
 
std::string executable_path()
Retrieve the path to the currently running executable.
 
void diag_flush(uint8 code, const String &txt)
Handle stdout and stderr printing with flushing.
 
size_t utf8_to_unicode(const char *str, uint32_t *codepoints)
 
constexpr bool unicode_is_character(uint32_t u)
Return whether u is not one of the 66 Unicode noncharacters.
 
const String & string_set_ascii_alnum()
Returns a string containing all of 0-9, A-Z and a-z.
 
bool ase_debugging_enabled
Global boolean to reduce debugging penalty where possible.
 
StringS string_split_any(const String &string, const String &splitchars, size_t maxn)
 
void debug_message(const char *cond, const std::string &message)
Print a debug message, called from Ase::debug().
 
std::string String
Convenience alias for std::string.
 
std::string executable_name()
Retrieve the name part of executable_path().
 
bool string_to_bool(const String &string, bool fallback)
 
::std::string debug_key_value(const char *conditional)
Retrieve the value assigned to debug key conditional in $ASE_DEBUG.
 
std::string_view string_option_find_value(const char *string, const char *feature, const char *fallback, const char *denied, bool matchallnone)
Low level option search, avoids dynamic allocations.
 
bool string_startswith(const String &string, const String &fragment)
Returns whether string starts with fragment.
 
#define TASSERT(cond)
Unconditional test assertion, enters breakpoint if not fullfilled.
 
IconString SvgIcon(const String &svgdata)
Create an IconString consisting of an SVG string.
 
IconString UcIcon(const String &unicode)
Create an IconString consisting of a single/double unicode character.
 
IconString KwIcon(const String &keywords)
Create an IconString consisting of keywords.