19extern inline unichar   totitle (
unichar uc)    { 
return g_unichar_totitle (uc); }
 
   26  return (c >= 
'A' && c <= 
'Z') || (c >= 
'a' && c <= 
'z') || (c >= 
'0' && c <= 
'9');
 
   56  static const String validset = ASE_STRING_SET_LOWER_ALNUM 
"_";
 
   59  if (!ident.
empty() && ident[0] <= 
'9')
 
 
   70  const size_t l = 
string.
size();
 
   71  const char *valids = valid_chars.
c_str(), *p = 
string.c_str();
 
   73  for (i = 0; i < l; i++)
 
   74    if (!
strchr (valids, p[i]))
 
 
   92  const size_t l = 
string.size();
 
   93  const char *valids = valid_chars.
c_str(), *p = 
string.c_str();
 
   94  for (
size_t i = 0; i < l; i++)
 
   95    if (!
strchr (valids, p[i]))
 
 
  104  static const String cached_a2z = 
"abcdefghijklmnopqrstuvwxyz";
 
 
  112  static const String cached_A2Z = 
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
 
  120  static const String cached_alnum = ASE_STRING_SET_ASCII_ALNUM;
 
 
  125string_is_ascii_alnum (
const String &str)
 
  128  for (
size_t i = 0; i < str.
size(); i++)
 
  129    if (!strchr (alnum.
c_str(), str[i]))
 
  139  for (
size_t i = 0; i < s.
size(); i++)
 
  140    s[i] = Unicode::tolower (s[i]);
 
 
  148  for (
size_t i = 0; i < str.
size(); i++)
 
  149    if (str[i] != Unicode::tolower (str[i]))
 
 
  159  for (
size_t i = 0; i < s.
size(); i++)
 
  160    s[i] = Unicode::toupper (s[i]);
 
 
  168  for (
size_t i = 0; i < str.
size(); i++)
 
  169    if (str[i] != Unicode::toupper (str[i]))
 
 
  179  for (
size_t i = 0; i < s.
size(); i++)
 
  180    s[i] = Unicode::totitle (s[i]);
 
 
  189  bool wasalpha = 
false;
 
  190  for (
size_t i = 0; i < s.
size(); i++)
 
  192      const bool atalpha = 
isalpha (s[i]);
 
  193      if (!wasalpha && atalpha)
 
  197          s[i] = Unicode::toupper (s[i]);
 
  200      else if (rest_tolower)
 
  201        s[i] = Unicode::tolower (s[i]);
 
 
  211  gchar *result = g_utf8_normalize (src.
c_str(), src.
size(), G_NORMALIZE_NFC);
 
  212  const String ret { result ? result : 
"" };
 
 
  221  gchar *result = g_utf8_normalize (src.
c_str(), src.
size(), G_NORMALIZE_NFD);
 
  222  const String ret { result ? result : 
"" };
 
 
  231  gchar *result = g_utf8_normalize (src.
c_str(), src.
size(), G_NORMALIZE_NFKC);
 
  232  const String ret { result ? result : 
"" };
 
 
  241  gchar *result = g_utf8_normalize (src.
c_str(), src.
size(), G_NORMALIZE_NFKD);
 
  242  const String ret { result ? result : 
"" };
 
 
  251  gchar *result = g_utf8_casefold (src.
c_str(), src.
size());
 
  252  const String ret { result ? result : 
"" };
 
 
  261  return g_utf8_collate (s1.
c_str(), s2.
c_str());
 
 
  273#define STACK_BUFFER_SIZE       3072 
  276current_locale_vprintf (
const char *format, 
va_list vargs)
 
  279  char buffer[STACK_BUFFER_SIZE];
 
  282  const int l = 
vsnprintf (buffer, 
sizeof (buffer), format, pargs);
 
  287  else if (
size_t (l) < 
sizeof (buffer))
 
  288    string = 
String (buffer, l);
 
  291      string.resize (l + 1);
 
  293      const int j = 
vsnprintf (&
string[0], 
string.size(), format, pargs);
 
  301posix_locale_vprintf (
const char *format, 
va_list vargs)
 
  304  return current_locale_vprintf (format, vargs);
 
  311  return posix_locale_vprintf (format, vargs);
 
 
  318  return current_locale_vprintf (format, vargs);
 
 
  322string_whitesplit (
const String &
string, 
size_t maxn)
 
  324  static const char whitespaces[] = 
" \t\n\r\f\v";
 
  327  for (i = 0; i < 
string.size() && sv.
size() < maxn; i++)
 
  328    if (strchr (whitespaces, 
string[i]))
 
  346    return string_whitesplit (
string, maxn);
 
  348  size_t i, l = 0, k = splitter.
size();
 
  349  for (i = 0; i < 
string.size() && sv.
size() < maxn; i++)
 
  350    if (
string.substr (i, k) == splitter)
 
 
  369  if (splitchars.
empty())
 
  371      for (i = 0; i < 
string.size() && sv.
size() < maxn; i++)
 
  373      if (i < 
string.size())
 
  374        sv.
push_back (
string.substr (i, 
string.size() - i));
 
  378      const char *schars = splitchars.
c_str();
 
  380      for (i = 0; i < 
string.size() && sv.
size() < maxn; i++)
 
  381        if (
strchr (schars, 
string[i]))
 
 
  395strings_version_sort (
const StringS &strings, 
bool reverse)
 
  398  strings_version_sort (&dest, reverse);
 
  403strings_version_sort (
StringS *strings, 
bool reverse)
 
  406  std::sort (strings->
begin(), strings->
end(), [reverse] (
auto &a, 
auto &b) -> 
bool {
 
  407    const int c = strverscmp (a.c_str(), b.c_str());
 
  408    return reverse ? c > 0 : c < 0;
 
  416  for (
size_t i = svector.
size(); i; i--)
 
  418      const size_t idx = i - 1;
 
  419      if (svector[idx].empty())
 
 
  428  for (
auto &s : svector)
 
 
  436  for (
auto &s : svector)
 
 
  444  for (
auto &s : svector)
 
 
  457  for (
uint i = 1; i < strvec.
size(); i++)
 
  458    s += junctor + strvec[i];
 
 
  469  return cstring_to_bool (
string.c_str(), fallback);
 
 
  473cstring_to_bool (
const char *
string, 
bool fallback)
 
  479  while (*p && isspace (*p))
 
  482  if (p[0] == 
'-' || p[0] == 
'+')
 
  486      while (*p && isspace (*p))
 
  490  if (p[0] >= 
'0' && p[0] <= 
'9')
 
  493  if (strncasecmp (p, 
"ON", 2) == 0)
 
  495  if (strncasecmp (p, 
"OFF", 3) == 0)
 
  501  return strchr (
"YyTt", p[0]);
 
  506strrstr (
const char *haystack, 
const char *needle)
 
  512  for (ssize_t i = h - n; i >= 0; i--)
 
  513    if (strncmp (haystack + i, needle, n) == 0)
 
  523  const size_t l = 
strlen (word);
 
  525  for (
const char *p = 
strstr (haystack, word); p; p = 
strstr (p + 1, word))
 
  526    if ((p == haystack || !c_isalnum (p[-1])) && !c_isalnum (p[l]))
 
 
  535  return String (value ? 
"1" : 
"0");
 
 
  542  const char *
const start = 
string.
c_str(), *p = start;
 
  543  while (*p == 
' ' || *p == 
'\n' || *p == 
'\t' || *p == 
'\r')
 
  545  const bool hex = p[0] == 
'0' && (p[1] == 
'X' || p[1] == 
'x');
 
  546  const char *
const number = hex ? p + 2 : p;
 
  548  const uint64 result = 
strtoull (number, &endptr, hex ? 16 : base);
 
  551      if (!endptr || endptr <= number)
 
  554        *consumed = endptr - start;
 
 
  570  const char *p = 
string.c_str();
 
  571  while (*p == 
' ' || *p == 
'\n' || *p == 
'\t' || *p == 
'\r')
 
  573  return p[0] >= 
'0' && p[0] <= 
'9';
 
 
  580  const char *
const start = 
string.c_str(), *p = start;
 
  581  while (*p == 
' ' || *p == 
'\n' || *p == 
'\t' || *p == 
'\r')
 
  583  const bool negate = p[0] == 
'-';
 
  586  const bool hex = p[0] == 
'0' && (p[1] == 
'X' || p[1] == 
'x');
 
  587  const char *
const number = hex ? p + 2 : p;
 
  592      if (!endptr || endptr <= number)
 
  595        *consumed = endptr - start;
 
  597  if (result < 9223372036854775808ull)
 
  598    return negate ? -
int64_t (result) : result;
 
  599  return negate ? -9223372036854775807ll - 1 : 9223372036854775808ull - 1;
 
 
  610libc_strtold (
const char *nptr, 
char **endptr)
 
  612  const long double result = 
strtold (nptr, endptr);
 
  615      const char *p = nptr;
 
  618      if (strncasecmp (p, 
"-nan", 4) == 0)
 
  629  char *fail_pos = NULL;
 
  630  const long double val = libc_strtold (nptr, &fail_pos);
 
 
  640  char *fail_pos_1 = NULL;
 
  642  if (fail_pos_1 && fail_pos_1[0] != 0)
 
  644      char *fail_pos_2 = NULL;
 
  645      const long double val_2 = libc_strtold (nptr, &fail_pos_2);
 
  646      if (fail_pos_2 > fail_pos_1)
 
  649            *endptr = fail_pos_2;
 
  654    *endptr = fail_pos_1;
 
 
  693    return std::signbit (value) ? 
"-Infinity" : 
"+Infinity";
 
 
  704    return std::signbit (value) ? 
"-Infinity" : 
"+Infinity";
 
 
  715    return std::signbit (value) ? 
"-Infinity" : 
"+Infinity";
 
 
  724  const char *spaces = 
" \t\n";
 
  725  const char *obrace = 
"{([";
 
  726  const char *delims = 
";";
 
  727  const char *cbrace = 
"])}";
 
  728  const char *number = 
"+-0123456789eE.,";
 
  729  const char *s = 
string.c_str();
 
  731  while (*s && 
strchr (spaces, *s))
 
  734  if (*s && 
strchr (obrace, *s))
 
  737  while (*d && !
strchr (cbrace, *d))
 
  739      while (*d && 
strchr (spaces, *d))         
 
  742      if (!*d || (!
strchr (number, *d) &&       
 
  745      while (*d && 
strchr (number, *d))         
 
  748      while (*d && 
strchr (spaces, *d))         
 
  750      if (*d && 
strchr (delims, *d))
 
 
  762  for (
uint i = 0; i < dvec.size(); i++)
 
 
  775  const char *fail = 
nullptr;
 
  776  const char *
const cs = 
string.
c_str();
 
  780  if (!fail || fail[0] == 
's')
 
  782  if (
strncmp (fail, 
"ns", 2) == 0)
 
  783    return d * 0.000000001;
 
  784  const char *usec = 
"µs";
 
  787  if (
strncmp (fail, 
"ms", 2) == 0)
 
  794    return d * 3600 * 24;
 
  796    return d * 3600 * 24 * 7;
 
 
  805    errno_val = -errno_val;     
 
  806  char buffer[1024] = { 0, };
 
  807  const char *errstr = 
strerror_r (errno_val, buffer, 
sizeof (buffer));
 
  808  if (!errstr || !errstr[0]) 
 
 
  817  int i, l = uuid_string.
size();
 
  821  for (i = 0; i < l; i++)
 
  822    if (i == 8 || i == 13 || i == 18 || i == 23)
 
  824        if (uuid_string[i] != 
'-')
 
  828    else if ((uuid_string[i] >= 
'0' && uuid_string[i] <= 
'9') ||
 
  829             (uuid_string[i] >= 
'a' && uuid_string[i] <= 
'f') ||
 
  830             (uuid_string[i] >= 
'A' && uuid_string[i] <= 
'F'))
 
 
  848  return fragment.
size() <= 
string.size() && 0 == 
string.compare (0, fragment.
size(), fragment);
 
 
  855  for (
const String &frag : fragments)
 
 
  865  return fragment.
size() <= 
string.size() && 0 == 
string.compare (
string.size() - fragment.
size(), fragment.
size(), fragment);
 
 
  872  for (
const String &frag : fragments)
 
 
  879identifier_char_canon (
char c)
 
  881  if (c >= 
'0' && c <= 
'9')
 
  883  else if (c >= 
'A' && c <= 
'Z')
 
  884    return c - 
'A' + 
'a';
 
  885  else if (c >= 
'a' && c <= 
'z')
 
  892identifier_match (
const char *str1, 
const char *str2)
 
  894  while (*str1 && *str2)
 
  896      const uint8 s1 = identifier_char_canon (*str1++);
 
  897      const uint8 s2 = identifier_char_canon (*str2++);
 
  901  return *str1 == 0 && *str2 == 0;
 
  905match_identifier_detailed (
const String &ident, 
const String &tail)
 
  908  const char *word = ident.
c_str() + ident.
size() - tail.
size();
 
  909  if (word > ident.
c_str()) 
 
  911      if (c_isalnum (word[-1]) && c_isalnum (word[0])) 
 
  914  return identifier_match (word, tail.
c_str());
 
  921  return ident.
size() >= tail.
size() && match_identifier_detailed (ident, tail);
 
 
  928  return ident1.
size() == ident2.
size() && match_identifier_detailed (ident1, ident2);
 
 
  940  const char *
const pretty_function = p2.
c_str();
 
  945  const char *op = 
strchr (pretty_function, 
'(');
 
  946  while (op && op[1] == 
'*')
 
  947    op = 
strchr (op + 1, 
'(');
 
  949    return pretty_function;
 
  951  const char *last = op - 1;
 
  952  while (last >= pretty_function && 
strchr (
" \t\n", *last))
 
  954  if (last < pretty_function)
 
  955    return pretty_function;
 
  957  const char *first = last;
 
  958  while (first >= pretty_function && 
strchr (
"0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ:abcdefghijklmnopqrstuvwxyz$", *first))
 
 
  969  for (
size_t i = 0; i < urlstr.
size(); i++)
 
  971      const char c = urlstr[i];
 
  974          const char buf[3] = { urlstr[i+1], urlstr[i+2], 0 };
 
  975          const long l = 
strtol (buf, 
nullptr, 16);
 
  979      else if (form_url_encoded && c == 
'+')
 
 
  993  const char *
const unescaped =  
"-._~"  "[]!()*";
 
  997    else if (form_url_encoded && c == 
' ')
 
 1001        const char *
const hex = 
"0123456789ABCDEF";
 
 1002        const char buf[4] = { 
'%', hex[c >> 4], hex[c & 0x0f], 0 };
 
 
 1014  for (String::const_iterator it = str.
begin(); it != str.
end(); it++)
 
 1016      const uint8 d = *it;
 
 1017      if      (d == 
'\a')       buffer +=  
"\\a";
 
 1018      else if (d == 
'\b')       buffer +=  
"\\b";
 
 1019      else if (d == 
'\t')       buffer +=  
"\\t";
 
 1020      else if (d == 
'\n')       buffer +=  
"\\n";
 
 1021      else if (d == 
'\v')       buffer +=  
"\\v";
 
 1022      else if (d == 
'\f')       buffer +=  
"\\f";
 
 1023      else if (d == 
'\r')       buffer +=  
"\\r";
 
 1024      else if (d == 
'"')        buffer += 
"\\\"";
 
 1025      else if (d == 
'\\')       buffer += 
"\\\\";
 
 1026      else if (d < 32 || d > 126)
 
 
 1046  if (i < input.
size() && (input[i] == 
'"' || input[i] == 
'\''))
 
 1048      const char qchar = input[i];
 
 1052      while (i < input.
size() && (input[i] != qchar || be))
 
 1054          if (!be && input[i] == 
'\\')
 
 1062                  case '0': 
case '1': 
case '2': 
case '3':
 
 1063                  case '4': 
case '5': 
case '6': 
case '7':
 
 1064                    k = 
MIN (input.
size(), i + 3);
 
 1065                    oc = input[i++] - 
'0';
 
 1066                    while (i < k && input[i] >= 
'0' && input[i] <= 
'7')
 
 1067                      oc = oc * 8 + input[i++] - 
'0';
 
 1071                  case 'a':     out += 
'\a';            
break;
 
 1072                  case 'n':     out += 
'\n';            
break;
 
 1073                  case 'r':     out += 
'\r';            
break;
 
 1074                  case 't':     out += 
'\t';            
break;
 
 1075                  case 'b':     out += 
'\b';            
break;
 
 1076                  case 'f':     out += 
'\f';            
break;
 
 1077                  case 'v':     out += 
'\v';            
break;
 
 1078                  default:      out += input[i];        
break;
 
 1086      if (i < input.
size() && input[i] == qchar)
 
 1089          if (i < input.
size())
 
 1096  else if (i == input.
size())
 
 
 1102static const char *whitespaces = 
" \t\v\f\n\r";
 
 1109  while (i < input.
size() && 
strchr (whitespaces, input[i]))
 
 1111  return i ? input.
substr (i) : input;
 
 
 1119  while (i > 0 && 
strchr (whitespaces, input[i - 1]))
 
 1121  return i < input.
size() ? input.
substr (0, i) : input;
 
 
 1129  while (a < input.
size() && 
strchr (whitespaces, input[a]))
 
 1132  while (b > 0 && 
strchr (whitespaces, input[b - 1]))
 
 1134  if (a == 0 && b == input.
size())
 
 1139    return input.
substr (a, b - a);
 
 
 1147  size_t i = s.
find (marker);
 
 1148  while (i != String::npos && maxn-- > 0)
 
 1151      i = s.
find (marker, i + replacement.
size());
 
 
 1163    for (String::size_type i = 0; i < output.
size(); i++)
 
 1164      if (output.
data()[i] == match)
 
 
 1175  for (
const char &c : input)
 
 
 1187  const unsigned char *data = (
const unsigned char*) addr;
 
 1189  String out, cx, cc = 
"|";
 
 1190  for (i = 0; i < length;)
 
 1195      cc += 
string_format (
"%c", data[i] < 
' ' || data[i] > 
'~' ? 
'.' : data[i]);
 
 1197      if (i && i % 16 == 0)
 
 
 1223  static_assert (
sizeof (*mem) == 4, 
"");
 
 1224  static_assert (
sizeof (filler) == 4, 
"");
 
 1225  static_assert (
sizeof (wchar_t) == 4, 
"");
 
 1226  wmemset ((
wchar_t*) mem, filler, length);
 
 
 1237  for (
size_t i = svector.
size(); i > 0; i--)
 
 1239      const String &s = svector[i-1];
 
 
 1254  for (
size_t i = svector.
size(); i > 0; i--)
 
 1256      const String &s = svector[i-1];
 
 
 1273      s = 
va_arg (args, 
const char*);
 
 1277          s = 
va_arg (args, 
const char*);
 
 
 1286kvpair_key (
const String &key_value_pair)
 
 1288  const char *
const eq = 
strchr (key_value_pair.
c_str(), 
'=');
 
 1289  return eq ? key_value_pair.
substr (0, eq - key_value_pair.
c_str()) : key_value_pair;
 
 1293kvpair_value (
const String &key_value_pair)
 
 1295  const char *
const eq = 
strchr (key_value_pair.
c_str(), 
'=');
 
 1296  return eq ? key_value_pair.
substr (eq - key_value_pair.
c_str() + 1) : 
"";
 
 1300kvpairs_fetch (
const StringS &kvs, 
const String &key, 
bool casesensitive)
 
 1302  const ssize_t i = kvpairs_search (kvs, key, casesensitive);
 
 1303  return i >= 0 ? kvs[i].
data() + key.
size() + 1 : 
"";
 
 1307kvpairs_search (
const StringS &kvs, 
const String &k, 
const bool casesensitive)
 
 1309  const size_t l = k.
size();
 
 1310  for (
size_t i = 0; i < kvs.
size(); i++)
 
 1311    if (kvs[i].
size() > l && kvs[i][l] == 
'=') {
 
 1312      if (casesensitive) {
 
 1313        if (strncmp (kvs[i].
data(), k.
data(), l) == 0)
 
 1316        if (strncasecmp (kvs[i].
data(), k.
data(), l) == 0)
 
 1324kvpairs_assign (
StringS &kvs, 
const String &key_value_pair, 
bool casesensitive)
 
 1326  const char *
const eq = 
strchr (key_value_pair.
c_str(), 
'=');
 
 1327  const String key = eq ? key_value_pair.
substr (0, eq - key_value_pair.
c_str()) : 
"";
 
 1329  const ssize_t i = kvpairs_search (kvs, key, casesensitive);
 
 1330  if (key_value_pair.
size() == key.
size() + 1 && key_value_pair[key_value_pair.
size()-1] == 
'=') {
 
 1335    kvs[i] = key_value_pair;            
 
 1342static bool is_separator (
char c) { 
return c == 
';' || c == 
':'; }
 
 1345find_option (
const char *haystack, 
const char *
const needle, 
const size_t l, 
const int allowoption)
 
 1347  const char *match = 
nullptr;
 
 1348  for (
const char *c = strcasestr (haystack, needle); c; c = strcasestr (c + 1, needle))
 
 1350        (c[l] == 0 && is_separator (c[l])) &&
 
 1351        ((c == haystack + 3 && 
strncasecmp (haystack, 
"no-", 3) == 0) ||
 
 1352         (c >= haystack + 4 && is_separator (haystack[0]) && 
strncasecmp (haystack + 1, 
"no-", 3) == 0)))
 
 1354    else if (allowoption &&
 
 1355             ((allowoption >= 2 && c[l] == 
'=') || c[l] == 0 || is_separator (c[l])) &&
 
 1356             (c == haystack || is_separator (c[-1])))
 
 1362separator_strlen (
const char *
const s)
 
 1365  while (c[0] && !is_separator (c[0]))
 
 1371string_option_find_value (
const char *
string, 
const char *feature, 
const char *fallback, 
const char *denied, 
const int matching)
 
 1373  if (!
string || !feature || !
string[0] || !feature[0])
 
 1374    return { fallback, 
strlen (fallback) };                     
 
 1375  const size_t l = 
strlen (feature);
 
 1376  const char *match = find_option (
string, feature, l, 2);      
 
 1377  if (matching >= 2) {
 
 1378    const char *deny = find_option (
string, feature, l, 0);     
 
 1380      return { denied, 
strlen (denied) };                       
 
 1382  if (match && match[l] == 
'=')
 
 1383    return { match + l + 1, separator_strlen (match + l + 1) }; 
 
 1386  if (matching >= 3) {
 
 1387    if (find_option (
string, 
"all", 3, 1))                      
 
 1389    if (find_option (
string, 
"none", 4, 1))                     
 
 1390      return { denied, 
strlen (denied) };                       
 
 1392  return { fallback, 
strlen (fallback) };                       
 
 1397string_option_find_value (
const char *
string, 
const char *feature, 
const char *fallback, 
const char *denied, 
bool matchallnone)
 
 1399  return string_option_find_value (
string, feature, fallback, denied, matchallnone ? 3 : 2);
 
 
 1418Strings::Strings (CS &s1)
 
 1420Strings::Strings (CS &s1, CS &s2)
 
 1422Strings::Strings (CS &s1, CS &s2, CS &s3)
 
 1424Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4)
 
 1426Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4, CS &s5)
 
 1428Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4, CS &s5, CS &s6)
 
 1430Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4, CS &s5, CS &s6, CS &s7)
 
 1432Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4, CS &s5, CS &s6, CS &s7, CS &s8)
 
 1435Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4, CS &s5, CS &s6, CS &s7, CS &s8, CS &s9)
 
 1438Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4, CS &s5, CS &s6, CS &s7, CS &s8, CS &s9, CS &sA)
 
 1441Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4, CS &s5, CS &s6, CS &s7, CS &s8, CS &s9, CS &sA, CS &sB)
 
 1444Strings::Strings (CS &s1, CS &s2, CS &s3, CS &s4, CS &s5, CS &s6, CS &s7, CS &s8, CS &s9, CS &sA, CS &sB, CS &sC)
 
 1450unalias_encoding (
String &name)
 
 1453  static const char *encoding_aliases[] = {
 
 1458    "ISO_646.IRV:1983", 
"ASCII",
 
 1461    "LATIN1",           
"ISO-8859-1",
 
 1462    "LATIN2",           
"ISO-8859-2",
 
 1463    "LATIN3",           
"ISO-8859-3",
 
 1464    "LATIN4",           
"ISO-8859-4",
 
 1465    "LATIN5",           
"ISO-8859-9",
 
 1466    "LATIN6",           
"ISO-8859-10",
 
 1467    "LATIN7",           
"ISO-8859-13",
 
 1468    "LATIN8",           
"ISO-8859-14",
 
 1469    "LATIN9",           
"ISO-8859-15",
 
 1470    "LATIN10",          
"ISO-8859-16",
 
 1471    "ISO8859-1",        
"ISO-8859-1",
 
 1472    "ISO8859-2",        
"ISO-8859-2",
 
 1473    "ISO8859-3",        
"ISO-8859-3",
 
 1474    "ISO8859-4",        
"ISO-8859-4",
 
 1475    "ISO8859-5",        
"ISO-8859-5",
 
 1476    "ISO8859-6",        
"ISO-8859-6",
 
 1477    "ISO8859-7",        
"ISO-8859-7",
 
 1478    "ISO8859-8",        
"ISO-8859-8",
 
 1479    "ISO8859-9",        
"ISO-8859-9",
 
 1480    "ISO8859-13",       
"ISO-8859-13",
 
 1481    "ISO8859-15",       
"ISO-8859-15",
 
 1482    "CP28591",          
"ISO-8859-1",
 
 1483    "CP28592",          
"ISO-8859-2",
 
 1484    "CP28593",          
"ISO-8859-3",
 
 1485    "CP28594",          
"ISO-8859-4",
 
 1486    "CP28595",          
"ISO-8859-5",
 
 1487    "CP28596",          
"ISO-8859-6",
 
 1488    "CP28597",          
"ISO-8859-7",
 
 1489    "CP28598",          
"ISO-8859-8",
 
 1490    "CP28599",          
"ISO-8859-9",
 
 1491    "CP28603",          
"ISO-8859-13",
 
 1492    "CP28605",          
"ISO-8859-15",
 
 1495    "IBM-eucCN",        
"GB2312",
 
 1496    "dechanzi",         
"GB2312",
 
 1498    "IBM-eucJP",        
"EUC-JP",
 
 1499    "sdeckanji",        
"EUC-JP",
 
 1501    "IBM-eucKR",        
"EUC-KR",
 
 1502    "deckorean",        
"EUC-KR",
 
 1504    "IBM-eucTW",        
"EUC-TW",
 
 1505    "CNS11643",         
"EUC-TW",
 
 1506    "CP20866",          
"KOI8-R",
 
 1509    "SJIS",             
"SHIFT_JIS",
 
 1512  for (
uint i = 0; i < 
sizeof (encoding_aliases) / 
sizeof (encoding_aliases[0]); i += 2)
 
 1513    if (strcasecmp (encoding_aliases[i], name.
c_str()) == 0)
 
 1515        name = encoding_aliases[i + 1];
 
 1520  for (
uint i = 0; i < upper.
size(); i++)
 
 1521    if (upper[i] >= 
'a' && upper[i] <= 
'z')
 
 1522      upper[i] += 
'A' - 
'a';
 
 1533aliased_iconv_open (
const String &tocode,
 
 1536  const iconv_t icNONE = (iconv_t) -1;
 
 1541  String to_encoding = tocode;
 
 1542  if (unalias_encoding (to_encoding))
 
 1548      String from_encoding = fromcode;
 
 1549      if (unalias_encoding (from_encoding))
 
 1557  String from_encoding = fromcode;
 
 1558  if (unalias_encoding (from_encoding))
 
 1575              const String &from_charset,
 
 1576              const String &input_string,
 
 1577              const String &fallback_charset,
 
 1578              const String &output_mark)
 
 1581  const iconv_t icNONE = (iconv_t) -1;
 
 1582  iconv_t alt_cd = icNONE, cd = aliased_iconv_open (to_charset, from_charset);
 
 1585  const char *iptr = input_string.
c_str();
 
 1586  size_t ilength = input_string.
size();
 
 1588  String alt_charset = fallback_charset;
 
 1592      char *optr = obuffer;
 
 1593      size_t olength = 
sizeof (obuffer);
 
 1594      size_t n = 
iconv (cd, 
const_cast<char**
> (&iptr), &ilength, &optr, &olength);
 
 1596      output_string.
append (obuffer, optr - obuffer);
 
 1605              if (alt_cd == icNONE && alt_charset.
size())
 
 1607                  alt_cd = aliased_iconv_open (to_charset, alt_charset);
 
 1610              size_t former_ilength = ilength;
 
 1611              if (alt_cd != icNONE)
 
 1615                  olength = 
sizeof (obuffer);
 
 1616                  n = 
iconv (alt_cd, 
const_cast<char**
> (&iptr), &ilength, &optr, &olength);
 
 1619                  output_string.
append (obuffer, optr - obuffer);
 
 1621              if (ilength == former_ilength)
 
 1624                  output_string += output_mark;
 
 1634  if (alt_cd != icNONE)
 
 
 1644  const int old_errno = 
errno;
 
 1648    result = ::strerror (errno_num);
 
 
 1672  s = 
"abcabc"; 
TASSERT (strrstr (s, 
"bc") == s + 4);
 
 1673  TASSERT (Ase::kvpair_key (
"foo=bar=baz") == 
"foo");
 
 1674  TASSERT (Ase::kvpair_value (
"foo=bar=baz") == 
"bar=baz");
 
 1755  TASSERT (typeid_name<::Ase::Strings>() == 
String (
"Ase::Strings"));
 
 1782  TASSERT (
string_cmp_uuid (
"c18888f8-f026-4f70-92dd-78D4B16E54D5", 
"C18888F8-f026-4f70-92dd-78d4b16e54d5") == 0);
 
 1783  TASSERT (
string_cmp_uuid (
"c18888f8-f026-4f70-92dd-78d4b16e54d4", 
"c18888f8-f026-4f70-92dd-78d4b16e54d5") < 0);
 
 1784  TASSERT (
string_cmp_uuid (
"c18888f8-f026-4f70-92dd-78d4b16e54d5", 
"c18888f8-f026-4f70-92dd-78d4b16e54d4") > 0);
 
Class to push the POSIX/C locale_t (UTF-8) for the scope of its lifetime.
 
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
 
#define MIN(a, b)
Yield minimum of a and b.
 
#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.
 
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 string_isupper(const String &str)
Check if all string characters are Unicode upper case characters.
 
String string_to_identifier(const String &input)
Force lower case, alphanumerics + underscore and non-digit start.
 
std::vector< double > string_to_double_vector(const String &string)
Parse a string into a list of doubles, expects ';' as delimiter.
 
int string_cmp(const String &s1, const String &s2)
Like strcmp(3) for UTF-8 strings.
 
String string_from_cquote(const String &input)
Parse a possibly quoted C string into regular string.
 
String string_from_errno(int errno_val)
Returns a String describing the passed in errno value, similar to strerror().
 
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
 
String string_casefold(const String &src)
Yield UTF-8 string useful for case insensitive comparisons.
 
String string_join(const String &junctor, const StringS &strvec)
 
bool string_is_uuid(const String &uuid_string)
Returns whether uuid_string contains a properly formatted UUID string.
 
String string_totitle(const String &str)
Convert all string characters into Unicode title characters.
 
String string_vprintf(const char *format, va_list vargs)
Formatted printing ala vprintf() into a String, using the POSIX/C locale.
 
StringS string_split(const String &string, const String &splitter, size_t maxn)
 
String string_hexdump(const void *addr, size_t length, size_t initial_offset)
 
bool string_is_canonified(const String &string, const String &valid_chars)
Check if string_canonify() would modify string.
 
String string_from_long_double(long double value)
Convert a long double into a string, using the POSIX/C locale.
 
String string_to_hex(const String &input)
Convert bytes in string input to hexadecimal numbers.
 
String string_from_double(double value)
Convert a double into a string, using the POSIX/C locale.
 
String string_tolower(const String &str)
Convert all string characters into Unicode lower case characters.
 
uint8_t uint8
An 8-bit unsigned integer.
 
bool string_match_identifier_tail(const String &ident, const String &tail)
Variant of string_match_identifier() that matches tail against ident at word boundary.
 
String string_lstrip(const String &input)
Strip whitespaces from the left of a string.
 
bool string_option_check(const String &optionlist, const String &feature)
Check if an option is set/unset in an options list string.
 
int64_t int64
A 64-bit unsigned integer, use PRI*64 in format strings.
 
String string_capitalize(const String &str, size_t maxn, bool rest_tolower)
Capitalize words, so the first letter is upper case, the rest lower case.
 
String string_vector_find_value(const StringS &svector, const String &prefix, const String &fallback)
 
String string_rstrip(const String &input)
Strip whitespaces from the right of a string.
 
String string_toupper(const String &str)
Convert all string characters into Unicode upper case characters.
 
String string_normalize_nfd(const String &src)
Yield normalized decomposed UTF-8 string.
 
int string_cmp_uuid(const String &uuid_string1, const String &uuid_string2)
Returns whether uuid_string1 compares smaller (-1), equal (0) or greater (+1) to uuid_string2.
 
int string_casecmp(const String &s1, const String &s2)
Like strcasecmp(3) for UTF-8 strings.
 
String string_from_int(int64 value)
Convert a 64bit signed integer into a string.
 
String string_from_uint(uint64 value)
Convert a 64bit unsigned integer into a string.
 
const char * string_find_word(const char *haystack, const char *word)
Find occurance of word in haystack.
 
String string_from_double_vector(const std::vector< double > &dvec, const String &delim)
Construct a string out of all double values passed in dvec, separated by delim.
 
void string_vector_erase_empty(StringS &svector)
Remove empty elements from a string vector.
 
long double posix_locale_strtold(const char *nptr, char **endptr)
Parse a double from a string ala strtod(), trying locale specific characters and POSIX/C formatting.
 
uint32_t unichar
A 32-bit unsigned integer used for Unicode characters.
 
String string_from_pretty_function_name(const char *cxx_pretty_function)
 
double string_to_seconds(const String &string, double fallback)
Parse string into seconds.
 
StringS cstrings_to_vector(const char *s,...)
Construct a StringS from a NULL terminated list of string arguments.
 
const String & string_set_ascii_alnum()
Returns a string containing all of 0-9, A-Z and a-z.
 
long double string_to_long_double(const String &string)
Parse a long double from a string, trying locale specific characters and POSIX/C formatting.
 
int64 string_to_int(const String &string, size_t *consumed, uint base)
Parse a string into a 64bit integer, optionally specifying the expected number base.
 
String string_replace(const String &input, const String &marker, const String &replacement, size_t maxn)
Replace substring marker in input with replacement, at most maxn times.
 
StringS string_split_any(const String &string, const String &splitchars, size_t maxn)
 
String string_normalize_nfkc(const String &src)
Formatting stripped normalized composed UTF-8 string.
 
void string_vector_strip(StringS &svector)
Strip all elements of a string vector, see string_strip().
 
String string_url_decode(const String &urlstr, const bool form_url_encoded)
Decode URL %-sequences in a string, decode '+' if form_url_encoded.
 
String string_option_find(const String &optionlist, const String &feature, const String &fallback)
Retrieve the option value from an options list separated by ':' or ';' or fallback.
 
uint64 string_to_uint(const String &string, size_t *consumed, uint base)
Parse a string into a 64bit unsigned integer, optionally specifying the expected number base.
 
double string_to_double(const String &string)
Parse a double from a string, trying locale specific characters and POSIX/C formatting.
 
const String & string_set_a2z()
Returns a string containing all of a-z.
 
bool string_has_int(const String &string)
Checks if a string contains a digit, optionally preceeded by whitespaces.
 
String string_normalize_nfkd(const String &src)
Formatting stripped normalized decomposed UTF-8 string.
 
String string_normalize_nfc(const String &src)
Yield normalized composed UTF-8 string.
 
std::string String
Convenience alias for std::string.
 
String string_vector_find(const StringS &svector, const String &prefix, const String &fallback)
 
bool string_to_bool(const String &string, bool fallback)
 
void string_vector_rstrip(StringS &svector)
Right-strip all elements of a string vector, see string_rstrip().
 
String string_multiply(const String &s, uint64 count)
Reproduce a string s for count times.
 
long double current_locale_strtold(const char *nptr, char **endptr)
Parse a double from a string ala strtod(), trying locale specific characters and POSIX/C formatting.
 
String string_canonify(const String &string, const String &valid_chars, const String &substitute)
 
String string_strip(const String &input)
Strip whitespaces from the left and right of a string.
 
const String & string_set_A2Z()
Returns a string containing all of A-Z.
 
String string_from_bool(bool value)
Convert a boolean value into a string.
 
uint32_t uint32
A 32-bit unsigned integer.
 
uint32_t uint
Provide 'uint' as convenience type.
 
String string_url_encode(const String &rawstr, const bool form_url_encoded)
Encode special characters to URL %-sequences, encode space as '+' if form_url_encoded.
 
bool string_endswith(const String &string, const String &fragment)
Returns whether string ends with fragment.
 
String string_substitute_char(const String &input, const char match, const char subst)
Replace all occouranes of match in input with subst.
 
bool string_islower(const String &str)
Check if all string characters are Unicode lower case characters.
 
bool string_match_identifier(const String &ident1, const String &ident2)
Check equality of strings canonicalized to "[0-9a-z_]+".
 
bool text_convert(const String &to_charset, String &output_string, const String &from_charset, const String &input_string, const String &fallback_charset, const String &output_mark)
 
String string_to_cquote(const String &str)
Returns a string as C string including double quotes.
 
String string_from_float(float value)
Convert a float into a string, using the POSIX/C locale.
 
void string_vector_lstrip(StringS &svector)
Left-strip all elements of a string vector, see string_lstrip().
 
void memset4(uint32 *mem, uint32 filler, uint length)
Fill a memory area with a 32-bit quantitiy.
 
String string_to_cescape(const String &str)
 
String string_locale_vprintf(const char *format, va_list vargs)
Formatted printing like string_vprintf using the current locale.
 
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.
 
#define TCMP(a, cmp, b)
Compare a and b according to operator cmp, verbose on failiure.