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.