53const char* strcasestr(
const char* s1,
const char* s2) {
57 size_t n = strlen(s2);
59 if (!strnicmp(s1++, s2, n))
132 while (*
start && isspace((
unsigned char)*
start))
135 char* end = s + strlen(s) - 1;
137 while (*end && isspace((
unsigned char)*end) && end > s) {
155 char* copy = strdup(s);
159 char* result = strdup(trimmed);
175 if (size >= INT_MAX) {
176 n_log(
LOG_ERR,
"size of %zu too big, >INT_MAX for buffer %p", size, buffer);
180 if (!fgets(buffer, (
int)size, stream)) {
213 n_log(
LOG_ERR,
"new_nstr: size %zu would wrap the terminator allocation", (
size_t)size);
241 n_log(
LOG_ERR,
"destination N_STR **str is not NULL (%p), it contain (%s). You must provide an empty destination.", (*to), ((*to) && (*to)->data) ? (*to)->data :
"DATA_IS_NULL");
251 memcpy((*to)->data, from, nboct);
252 (*to)->written = nboct;
264 N_STR* strptr = NULL;
265 size_t length = strlen(src);
296 N_STR* tmpstr = NULL;
297 struct stat filestat;
303 int fd = open(filename, O_RDONLY);
306 n_log(
LOG_ERR,
"Unable to open %s for reading. Errno: %s", filename, strerror(error));
310 if (fstat(fd, &filestat) != 0) {
313 if (error == EOVERFLOW) {
314 n_log(
LOG_ERR,
"%s size is too big ,EOVERFLOW)", filename);
317 n_log(
LOG_ERR,
"Couldn't stat %s. Errno: %s", filename, strerror(error));
325 if ((uint64_t)filestat.st_size >= (uint64_t)UINT32_MAX) {
326 n_log(
LOG_ERR,
"file size >= 4GB is not possible yet. %s is %lld oct", filename, (
long long)filestat.st_size);
331 n_log(
LOG_DEBUG,
"%s file size is: %lld", filename, (
long long)filestat.st_size);
333 in = fdopen(fd,
"rb");
335 n_log(
LOG_ERR,
"fdopen failed on %s (fd=%d)", filename, fd);
340 tmpstr =
new_nstr((
size_t)filestat.st_size + 1);
341 __n_assert(tmpstr, fclose(in);
n_log(
LOG_ERR,
"Unable to get a new nstr of %lld octets", (
long long)filestat.st_size + 1);
return NULL);
343 tmpstr->
written = (size_t)filestat.st_size;
350 if (fread(tmpstr->
data,
sizeof(
char), tmpstr->
written, in) == 0) {
351 n_log(
LOG_ERR,
"Couldn't read %s, fread return 0", filename);
357 n_log(
LOG_ERR,
"There were some errors when reading %s", filename);
380 struct flock out_lock;
389 memset(&out_lock, 0,
sizeof(out_lock));
390 out_lock.l_type = F_WRLCK;
392 fcntl(fileno(out), F_SETLKW, &out_lock);
399 size_t written_to_file = 0;
400 if ((written_to_file = fwrite(str->
data,
sizeof(
char), str->
written, out)) != (
size_t)str->
written) {
401 n_log(
LOG_ERR,
"Couldn't write file, fwrite %zu of %zu octets", written_to_file, str->
written);
405 n_log(
LOG_ERR,
"There were some errors when writing to %d", fileno(out));
411 memset(&out_lock, 0,
sizeof(out_lock));
412 out_lock.l_type = F_WRLCK;
414 fcntl(fileno(out), F_SETLKW, &out_lock);
435 int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0600);
437 n_log(
LOG_ERR,
"Couldn't open %s for writing (0600). Errno: %s",
_str(filename), strerror(errno));
442 out = fdopen(fd,
"wb");
444 n_log(
LOG_ERR,
"fdopen failed for %s (fd=%d). Errno: %s",
_str(filename), fd, strerror(errno));
476 if (
start > end)
return FALSE;
478 Malloc(tmpstr,
char,
sizeof(
int) + end -
start + 8);
484 l = strtol(tmpstr, &endstr, base);
485 if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX) {
486 n_log(
LOG_ERR,
"OVERFLOW reached when converting %s to int", tmpstr);
490 if ((errno == ERANGE && l == LONG_MIN) || l < INT_MIN) {
491 n_log(
LOG_ERR,
"UNDERFLOW reached when converting %s to int", tmpstr);
495 if (*endstr !=
'\0' && *endstr !=
'\n') {
524 if (
start > end)
return FALSE;
526 Malloc(tmpstr,
char,
sizeof(
int) + end -
start + 8);
532 l = strtol(tmpstr, &endstr, base);
533 if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX) {
534 nstrprintf((*infos),
"OVERFLOW reached when converting %s to int", tmpstr);
538 if ((errno == ERANGE && l == LONG_MIN) || l < INT_MIN) {
539 nstrprintf((*infos),
"UNDERFLOW reached when converting %s to int", tmpstr);
543 if (*endstr !=
'\0' && *endstr !=
'\n') {
544 nstrprintf((*infos),
"Impossible conversion for %s", tmpstr);
586 if (
start > end)
return FALSE;
588 Malloc(tmpstr,
char,
sizeof(
int) + end -
start + 8);
594 l = strtol(tmpstr, &endstr, base);
598 if (tmpstr == endstr) {
599 n_log(
LOG_ERR,
" number : %ld invalid (no digits found, 0 returned)", l);
602 }
else if (error == ERANGE && l == LONG_MIN) {
603 n_log(
LOG_ERR,
" number : %ld invalid (underflow occurred)", l);
606 }
else if (error == ERANGE && l == LONG_MAX) {
607 n_log(
LOG_ERR,
" number : %ld invalid (overflow occurred)", l);
610 }
else if (error == EINVAL)
612 n_log(
LOG_ERR,
" number : %ld invalid (base contains unsupported value)", l);
615 }
else if (error != 0 && l == 0) {
616 n_log(
LOG_ERR,
" number : %ld invalid (unspecified error occurred)", l);
619 }
else if (error == 0 && !*endstr) {
620 n_log(
LOG_DEBUG,
" number : %ld valid (and represents all characters read)", l);
621 }
else if (error == 0 && *endstr != 0) {
622 n_log(
LOG_DEBUG,
" number : %ld valid (but additional characters remain", l);
645 if (
start > end)
return FALSE;
647 Malloc(tmpstr,
char,
sizeof(
int) + end -
start + 8);
653 l = strtoll(tmpstr, &endstr, base);
657 if (tmpstr == endstr) {
658 n_log(
LOG_ERR,
"number: '%s' invalid (no digits found, 0 returned)", s);
661 }
else if (error == ERANGE && l == LLONG_MIN) {
662 n_log(
LOG_ERR,
"number: '%s' invalid (underflow occurred)", s);
665 }
else if (error == ERANGE && l == LLONG_MAX) {
666 n_log(
LOG_ERR,
"number: '%s' invalid (overflow occurred)", s);
669 }
else if (error == EINVAL)
671 n_log(
LOG_ERR,
"number: '%s' invalid (base contains unsupported value)", s);
674 }
else if (error != 0 && l == 0) {
675 n_log(
LOG_ERR,
"number: '%s' invalid (unspecified error occurred)", s);
678 }
else if (error == 0 && !*endstr) {
679 n_log(
LOG_DEBUG,
"number : '%llu' valid (and represents all characters read)", l);
680 }
else if (error == 0 && *endstr != 0) {
681 n_log(
LOG_DEBUG,
" number : '%llu' valid (remaining characters: '%s')", l, s);
724 N_STR* new_str = NULL;
737 n_log(
LOG_ERR,
"Error duplicating N_STR %p -> data", str);
761 while (*iterator <= slen && isspace((
unsigned char)
string[*iterator])) {
762 if (inc < 0 && *iterator == 0) {
767 *iterator = *iterator + (
NSTRBYTE)inc;
769 *iterator = (*iterator > (
NSTRBYTE)(-inc)) ? (*iterator - (
NSTRBYTE)(-inc)) : 0;
773 while (*iterator <= slen &&
string[*iterator] == toskip) {
774 if (inc < 0 && *iterator == 0) {
779 *iterator = *iterator + (
NSTRBYTE)inc;
781 *iterator = (*iterator > (
NSTRBYTE)(-inc)) ? (*iterator - (
NSTRBYTE)(-inc)) : 0;
785 if (error_flag == 1 || *iterator > slen) {
808 while (*iterator <= slen && !isspace((
unsigned char)
string[*iterator])) {
809 if (inc < 0 && *iterator == 0) {
814 *iterator = *iterator + (
NSTRBYTE)inc;
816 *iterator = (*iterator > (
NSTRBYTE)(-inc)) ? (*iterator - (
NSTRBYTE)(-inc)) : 0;
820 while (*iterator <= slen &&
string[*iterator] != toskip) {
821 if (inc < 0 && *iterator == 0) {
826 *iterator = *iterator + (
NSTRBYTE)inc;
828 *iterator = (*iterator > (
NSTRBYTE)(-inc)) ? (*iterator - (
NSTRBYTE)(-inc)) : 0;
833 if (error_flag == 1 || *iterator > slen) {
847int strup(
const char*
string,
char* dest) {
853 for (it = 0; it < (
NSTRBYTE)strlen(
string); it++)
854 dest[it] = (
char)toupper(
string[it]);
856 dest[strlen(
string)] =
'\0';
868int strlo(
const char*
string,
char* dest) {
874 for (it = 0; it < (
NSTRBYTE)strlen(
string); it++)
875 dest[it] = (
char)tolower(
string[it]);
877 dest[strlen(
string)] =
'\0';
898 while (_it < to_size && from[(*it)] !=
'\0' && from[(*it)] != delim) {
899 to[_it] = from[(*it)];
904 if (_it == to_size) {
907 n_log(
LOG_DEBUG,
"strcpy_u: not enough space to write %zu octet to dest (%zu max) , %s: %d", _it, to_size, __FILE__, __LINE__);
913 if (from[(*it)] != delim) {
914 n_log(
LOG_DEBUG,
"strcpy_u: delim value not found, written %zu octet to dest (%zu max) , %s: %d", _it, to_size, __FILE__, __LINE__);
927char**
split(
const char* str,
const char* delim,
int empty) {
929 const char* ptr = NULL;
933 const char* largestring = NULL;
938 size_t sizeDelim = strlen(delim);
941 while ((ptr = strstr(largestring, delim)) != NULL) {
942 sizeStr = (size_t)(ptr - largestring);
943 if (empty == 1 || sizeStr != 0) {
945 tmp = (
char**)realloc(tab,
sizeof(
char*) * sizeTab);
949 Malloc(tab[sizeTab - 1],
char,
sizeof(
char) * (sizeStr + 1));
952 memcpy(tab[sizeTab - 1], largestring, sizeStr);
953 tab[sizeTab - 1][sizeStr] =
'\0';
955 ptr = ptr + sizeDelim;
960 if (strlen(largestring) != 0) {
961 sizeStr = strlen(largestring);
964 tmp = (
char**)realloc(tab,
sizeof(
char*) * sizeTab);
968 Malloc(tab[sizeTab - 1],
char,
sizeof(
char) * (sizeStr + 1));
971 memcpy(tab[sizeTab - 1], largestring, sizeStr);
972 tab[sizeTab - 1][sizeStr] =
'\0';
977 tmp = (
char**)realloc(tab,
sizeof(
char*) * sizeTab);
981 Malloc(tab[sizeTab - 1],
char, (
int)(
sizeof(
char) * 1));
984 tab[sizeTab - 1][0] =
'\0';
990 tmp = (
char**)realloc(tab,
sizeof(
char*) * sizeTab);
993 tab[sizeTab - 1] = NULL;
1012 while (split_result[it]) {
1028 while ((*tab)[it]) {
1044char*
join(
char** splitresult,
const char* delim) {
1045 size_t delim_length = 0;
1047 delim_length = strlen(delim);
1048 size_t total_length = 0;
1050 while (splitresult[it]) {
1052 size_t entry_length = strlen(splitresult[it]);
1053 if (entry_length >= SIZE_MAX - total_length) {
1054 n_log(
LOG_ERR,
"join: total_length overflow accumulating entry %d", it);
1057 total_length += entry_length;
1059 if (delim && splitresult[it + 1]) {
1060 if (delim_length >= SIZE_MAX - total_length) {
1061 n_log(
LOG_ERR,
"join: total_length overflow accumulating delimiter at entry %d", it);
1064 total_length += delim_length;
1068 char* result = NULL;
1069 Malloc(result,
char, total_length + 1);
1071 size_t position = 0;
1073 while (splitresult[it]) {
1074 size_t copy_size = strlen(splitresult[it]);
1075 memcpy(&result[position], splitresult[it], copy_size);
1076 position += copy_size;
1078 if (delim && splitresult[it + 1]) {
1079 memcpy(&result[position], delim, delim_length);
1080 position += delim_length;
1084 result[position] =
'\0';
1101 if (size >= SIZE_MAX - 1) {
1102 n_log(
LOG_ERR,
"size too large in nstrcat_ex: %zu", size);
1106 if (resize_flag == 0) {
1109 if (size > SIZE_MAX - (*dest)->written - 1) {
1110 n_log(
LOG_ERR,
"integer overflow in nstrcat_ex size calculation");
1113 if (((*dest)->written + size + 1) > (*dest)->length) {
1114 n_log(
LOG_ERR,
"%p to %p: not enough space. Resize forbidden. %zu needed, %zu available", src, (*dest), (*dest)->written + size + 1, (*dest)->length);
1118 n_log(
LOG_ERR,
"%p to %p: not enough space. Resize forbidden. %zu needed, destination is NULL", src, (*dest), size + 1);
1126 n_log(
LOG_ERR,
"could not allocate new N_STR of size %zu", size + 1);
1132 if (size > SIZE_MAX - (*dest)->written - 1) {
1133 n_log(
LOG_ERR,
"integer overflow in nstrcat_ex size calculation");
1137 if ((*dest)->length < (*dest)->written + size + 1) {
1138 (*dest)->length = (*dest)->written + size + 1;
1139 if (
Reallocz((*dest)->data,
char, (*dest)->written, (*dest)->length) == FALSE) {
1145 ptr = (*dest)->data + (*dest)->written;
1146 memcpy(ptr, src, size);
1147 (*dest)->written += size;
1149 (*dest)->data[(*dest)->written] =
'\0';
1165 n_log(
LOG_ERR,
"Could not copy 0 or less (%zu) octet!", size);
1195 if (src_size == 0)
return TRUE;
1196 NSTRBYTE needed_size = (*written) + src_size + 1;
1197 NSTRBYTE alloc_size = needed_size + additional_padding;
1200 if (alloc_size < needed_size)
return FALSE;
1203 if ((needed_size >= (*size)) || !(*dest)) {
1208 if (
Reallocz((*dest),
char, (*size), alloc_size) == FALSE) {
1214 (*size) = alloc_size;
1216 char* ptr = (*dest) + (*written);
1217 memcpy(ptr, src, src_size);
1218 (*written) += src_size;
1219 (*dest)[(*written)] =
'\0';
1262 struct dirent* entry = NULL;
1263 struct stat statbuf;
1268 if ((dp = opendir(dir)) == NULL) {
1273 N_STR* newname = NULL;
1274 while ((entry = readdir(dp)) != NULL) {
1275 if (!
nstrprintf(newname,
"%s/%s", dir, entry->d_name)) {
1276 n_log(
LOG_ERR,
"could not allocate newname for %s/%s", dir, entry->d_name);
1281 if (stat(newname->
data, &statbuf) >= 0) {
1282 if (S_ISDIR(statbuf.st_mode) != 0) {
1283 if (strcmp(
".", entry->d_name) == 0 || strcmp(
"..", entry->d_name) == 0) {
1289 if (recurse != FALSE) {
1291 n_log(
LOG_ERR,
"scan_dir_ex( %s , %s , %p , %d , %d ) returned FALSE !", newname->
data, pattern, result, recurse,
mode);
1296 }
else if (S_ISREG(statbuf.st_mode) != 0) {
1299 char* file = strdup(newname->
data);
1303 n_log(
LOG_ERR,
"Error adding %s/%s to list", dir, entry->d_name);
1305 }
else if (
mode == 1) {
1326 register int last = 0;
1327 register int matched = 0;
1328 register int reverse = 0;
1330 for (; *p;
text++, p++) {
1331 if (*
text ==
'\0' && *p !=
'*')
1362 if (p[1] ==
']' || p[1] ==
'-')
1365 for (
last = *p; *++p && *p !=
']';
last = *p)
1367 if (*p ==
'-' && p[1] !=
']'
1371 if (matched == reverse)
1376#ifdef WILDMAT_MATCH_TAR_PATTERN
1380 return *
text ==
'\0';
1391 register int matched;
1392 register int reverse;
1394 for (; *p;
text++, p++) {
1395 if (*
text ==
'\0' && *p !=
'*')
1403 if (toupper(*
text) != toupper(*p))
1426 if (p[1] ==
']' || p[1] ==
'-')
1427 if (toupper(*++p) == toupper(*
text))
1429 for (
last = toupper(*p); *++p && *p !=
']';
last = toupper(*p))
1430 if (*p ==
'-' && p[1] !=
']'
1431 ? toupper(*
text) <= toupper(*++p) && toupper(*
text) >=
last
1432 : toupper(*
text) == toupper(*p))
1434 if (matched == reverse)
1439#ifdef WILDMAT_MATCH_TAR_PATTERN
1443 return *
text ==
'\0';
1460char*
str_replace(
const char*
string,
const char* substr,
const char* replacement) {
1461 size_t string_len = 0, substr_len = 0, replacement_len = 0, count = 0, result_len = 0;
1462 const char* scan = NULL;
1463 char* result = NULL;
1466 if (!
string)
return NULL;
1467 if (!substr || !substr[0] || !replacement)
return strdup(
string);
1468 string_len = strlen(
string);
1469 substr_len = strlen(substr);
1470 replacement_len = strlen(replacement);
1471 for (scan = strstr(
string, substr); scan; scan = strstr(scan + substr_len, substr)) count++;
1474 result_len = string_len - count * substr_len;
1475 if (replacement_len && count > (SIZE_MAX - 1 - result_len) / replacement_len) {
1476 n_log(
LOG_ERR,
"str_replace: the result would be too large (%zu occurrences of %zu bytes)", count,
1480 result_len += count * replacement_len;
1481 Malloc(result,
char, result_len + 1);
1483 n_log(
LOG_ERR,
"str_replace: could not allocate %zu bytes", result_len + 1);
1487 for (scan =
string; count > 0; count--) {
1488 const char* found = strstr(scan, substr);
1489 size_t before = (size_t)(found - scan);
1491 memcpy(out, scan, before);
1493 memcpy(out, replacement, replacement_len);
1494 out += replacement_len;
1495 scan = found + substr_len;
1497 memcpy(out, scan, strlen(scan) + 1);
1525 const unsigned char* pa = (
const unsigned char*)a;
1526 const unsigned char* pb = (
const unsigned char*)b;
1527 const unsigned char*
const enda = pa + alen;
1528 const unsigned char*
const endb = pb + blen;
1529 int zeros = 0, c = 0;
1532 if (!a || !b)
return (a == b) ? 0 : (!a ? -1 : 1);
1533 while (pa < enda && pb < endb) {
1534 if (*pa >=
'0' && *pa <=
'9' && *pb >=
'0' && *pb <=
'9') {
1535 const unsigned char* sa = pa;
1536 const unsigned char* sb = pb;
1537 const unsigned char* ea = NULL;
1538 const unsigned char* eb = NULL;
1540 while (sa < enda && *sa ==
'0') sa++;
1541 while (sb < endb && *sb ==
'0') sb++;
1542 for (ea = sa; ea < enda && *ea >=
'0' && *ea <=
'9'; ea++);
1543 for (eb = sb; eb < endb && *eb >=
'0' && *eb <=
'9'; eb++);
1545 if (ea - sa != eb - sb)
return (ea - sa) < (eb - sb) ? -1 : 1;
1546 c = memcmp(sa, sb, (
size_t)(ea - sa));
1547 if (c)
return c < 0 ? -1 : 1;
1550 if (!zeros && (sa - pa) != (sb - pb)) zeros = (sa - pa) < (sb - pb) ? -1 : 1;
1554 unsigned char ca = *pa, cb = *pb;
1556 if (ca >=
'A' && ca <=
'Z') ca = (
unsigned char)(ca -
'A' +
'a');
1557 if (cb >=
'A' && cb <=
'Z') cb = (
unsigned char)(cb -
'A' +
'a');
1558 if (ca != cb)
return ca < cb ? -1 : 1;
1563 if (pa < enda)
return 1;
1564 if (pb < endb)
return -1;
1565 if (zeros)
return zeros;
1566 common = alen < blen ? alen : blen;
1567 c = common ? memcmp(a, b, common) : 0;
1568 if (c)
return c < 0 ? -1 : 1;
1569 return alen == blen ? 0 : (alen < blen ? -1 : 1);
1600 for (it = 0; it < string_len; it++) {
1602 while (mask_it < masklen && mask[mask_it] !=
'\0') {
1603 if (
string[it] == mask[mask_it])
1604 string[it] = replacement;
1619 return str_sanitize_ex(
string, strlen(
string), mask, strlen(mask), replacement);
1664 int needed_size = 0;
1667 va_start(args, format);
1668 va_copy(args_copy, args);
1669 needed_size = vsnprintf(NULL, 0, format, args);
1672 if (needed_size < 0) {
1674 n_log(
LOG_ERR,
"there was an error while computing the new size according to format \"%s\" for N_STR %p", format, (*nstr_var));
1678 size_t needed = (size_t)(needed_size + 1);
1683 if (!(*nstr_var) || !(*nstr_var)->data) {
1685 n_log(
LOG_ERR,
"could not allocate N_STR of size %zu", needed);
1688 }
else if (needed > (*nstr_var)->length) {
1691 n_log(
LOG_ERR,
"could not resize N_STR %p to size %zu", (*nstr_var), needed);
1697 vsnprintf((*nstr_var)->data, needed, format, args_copy);
1700 (*nstr_var)->written = (size_t)needed_size;
1715 va_start(args, format);
1719 va_copy(args_copy, args);
1722 int needed_size = vsnprintf(NULL, 0, format, args_copy);
1725 if (needed_size < 0) {
1726 n_log(
LOG_ERR,
"vsnprintf size estimation failed for format \"%s\"", format);
1731 size_t needed = (size_t)(needed_size + 1);
1743 if (needed > SIZE_MAX - (*nstr_var)->written) {
1745 n_log(
LOG_ERR,
"integer overflow computing total_needed in nstrprintf_cat_ex");
1750 size_t total_needed = (*nstr_var)->written + needed;
1751 if (total_needed > (*nstr_var)->length) {
1752 if (
resize_nstr((*nstr_var), total_needed) == FALSE) {
1754 n_log(
LOG_ERR,
"could not resize N_STR %p to size %zu", (*nstr_var), total_needed);
1760 char* write_ptr = (*nstr_var)->data + (*nstr_var)->written;
1761 int written_now = vsnprintf(write_ptr, needed, format, args);
1764 if (written_now < 0) {
1765 n_log(
LOG_ERR,
"vsnprintf failed while writing at offset %zu in N_STR %p", (*nstr_var)->written, (*nstr_var));
1769 (*nstr_var)->written += (size_t)written_now;
1770 (*nstr_var)->data[(*nstr_var)->written] =
'\0';
1776 if (!tmpl)
return NULL;
1778 if (!result)
return NULL;
1779 const char* p = tmpl;
1781 if (p[0] ==
'{' && p[1] ==
'{') {
1782 const char* end = strstr(p + 2,
"}}");
1784 size_t klen = (size_t)(end - (p + 2));
1786 if (klen <
sizeof(
key)) {
1787 memcpy(
key, p + 2, klen);
1800 char ch[2] = {*p,
'\0'};
1820 if (!src)
return NULL;
1821 size_t in_len = strlen(src);
1823 if (in_len > (SIZE_MAX - 1) / 3)
return NULL;
1825 if (!out)
return NULL;
1826 for (
const unsigned char* p = (
const unsigned char*)src; *p; p++) {
1827 unsigned char c = *p;
1828 if ((c >=
'A' && c <=
'Z') || (c >=
'a' && c <=
'z') ||
1829 (c >=
'0' && c <=
'9') ||
1830 c ==
'-' || c ==
'_' || c ==
'.' || c ==
'~') {
1831 char ch[2] = {(char)c,
'\0'};
1856 const unsigned char* p = (
const unsigned char*)s;
1859 return len == 0 ? TRUE : FALSE;
1861 unsigned char c = p[i];
1868 if (c >= 0xC2 && c <= 0xDF) {
1871 }
else if (c >= 0xE0 && c <= 0xEF) {
1874 }
else if (c >= 0xF0 && c <= 0xF4) {
1880 if (len - i - 1 < need)
1882 for (
size_t k = 1; k <= need; k++) {
1883 if ((p[i + k] & 0xC0u) != 0x80u)
1885 cp = (cp << 6) | (p[i + k] & 0x3Fu);
1887 if ((need == 2 && cp < 0x800) || (need == 3 && cp < 0x10000) ||
1888 (cp >= 0xD800 && cp <= 0xDFFF) || cp > 0x10FFFF)
static N_GUI_MOUSE_EVENT last
the last event the widget was told of, and how many
static N_HTTP_RESP * text(int status, const char *body)
text response
static N_HTTP_SERVER * start(N_HTTP_SERVER_CONFIG *cfg, char *port, int base)
start a server on the first free port from base
volatile char key[227]
TRUE while the key is held.
#define FreeNoLog(__ptr)
Free Handler without log.
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
#define __n_assert(__ptr, __ret)
macro to assert things
#define _str(__PTR)
define true
#define Reallocz(__ptr, __struct, __old_size, __size)
Realloc + zero new memory zone Handler to get errors.
#define Free(__ptr)
Free Handler to get errors.
int ht_get_string(HASH_TABLE *table, const char *key, char **val)
get string at 'key' from 'table'
structure of a hash table
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
Structure of a generic LIST container.
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_DEBUG
debug-level messages
#define LOG_ERR
error conditions
size_t written
number of meaningful bytes in data, excluding the null terminator; the size including the null termin...
size_t length
total allocation (in bytes) of the data buffer, padding included
int str_to_long_long(const char *s, long long int *i, const int base)
Helper for string to integer.
N_STR * n_str_template_expand(const char *tmpl, HASH_TABLE *vars)
Expand double-brace tokens in a template using a hash table.
char * trim_nocopy(char *s)
trim and zero end the string, WARNING: keep and original pointer to delete the string correctly
void free_nstr_ptr(void *ptr)
Free a N_STR pointer structure.
N_STR * nstrprintf_cat_ex(N_STR **nstr_var, const char *format,...)
Function to allocate, format, and concatenate a string into an N_STR object.
N_STR * n_str_url_encode(const char *src)
Percent-encode a C string per RFC 3986 (unreserved set kept as-is).
size_t NSTRBYTE
N_STR base unit.
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
int split_count(char **split_result)
Count split elements.
int str_natncasecmp(const char *a, size_t alen, const char *b, size_t blen)
Compare two byte runs in natural order, ignoring ASCII case.
int str_sanitize_ex(char *string, const NSTRBYTE string_len, const char *mask, const NSTRBYTE masklen, const char replacement)
clean a string by replacing evil characteres
int nstr_to_file(N_STR *str, char *filename)
Write a N_STR content into a file.
int scan_dir_ex(const char *dir, const char *pattern, LIST *result, const int recurse, const int mode)
Scan a list of directory and return a list of char *file.
int str_to_long_long_ex(const char *s, NSTRBYTE start, NSTRBYTE end, long long int *i, const int base)
Helper for string[start to end] to long long integer.
char * join(char **splitresult, const char *delim)
join the array into a string
N_STR * nstrdup(N_STR *str)
Duplicate a N_STR.
int strlo(const char *string, char *dest)
Lower case a string.
N_STR * nstrcat_ex(N_STR **dest, void *src, NSTRBYTE size, int resize_flag)
Append data into N_STR using internal N_STR size and cursor position.
int write_and_fit(char **dest, NSTRBYTE *size, NSTRBYTE *written, const char *src)
Append src to *dest.
#define nstrprintf_cat(__nstr_var, __format,...)
Macro to quickly allocate and sprintf and cat to a N_STR.
int strcpy_u(const char *from, char *to, NSTRBYTE to_size, char delim, NSTRBYTE *it)
Copy from start to dest until from[ iterator ] == delim.
int str_to_int_ex(const char *s, NSTRBYTE start, NSTRBYTE end, int *i, const int base)
Helper for string[start to end] to integer.
int str_to_int_nolog(const char *s, NSTRBYTE start, NSTRBYTE end, int *i, const int base, N_STR **infos)
Helper for string[start to end] to integer.
int resize_nstr(N_STR *nstr, size_t size)
reallocate a nstr internal buffer.
N_STR * char_to_nstr(const char *src)
Convert a char into a N_STR, short version.
char * nfgets(char *buffer, NSTRBYTE size, FILE *stream)
try to fgets
int skipu(const char *string, char toskip, NSTRBYTE *iterator, int inc)
skip until 'toskip' occurence is found from 'iterator' to the next 'toskip' value.
#define WILDMAT_ABORT
Abort code to sped up pattern matching.
int empty_nstr(N_STR *nstr)
empty a N_STR string
int wildmatcase(register const char *text, register const char *p)
Written by Rich Salz rsalz at osf.org, refurbished by me.
#define WILDMAT_NEGATE_CLASS
What character marks an inverted character class?
N_STR * new_nstr(NSTRBYTE size)
create a new N_STR string
char * str_replace(const char *string, const char *substr, const char *replacement)
Replace every occurrence of substr by replacement in a copy of string.
char * trim(const char *s)
trim and put a \0 at the end, return new char *
int skipw(const char *string, char toskip, NSTRBYTE *iterator, int inc)
skip while 'toskip' occurence is found from 'iterator' to the next non 'toskip' position.
#define nstrprintf(__nstr_var, __format,...)
Macro to quickly allocate and sprintf to N_STR.
int str_natcasecmp(const char *a, const char *b)
Compare two strings in natural order, ignoring ASCII case.
N_STR * nstrcat_bytes_ex(N_STR **dest, void *data, NSTRBYTE size)
Append data into N_STR using internal N_STR size and cursor position.
int scan_dir(const char *dir, LIST *result, const int recurse)
Scan a list of directory and return a list of char *file.
int str_sanitize(char *string, const char *mask, const char replacement)
clean a string by replacing evil characteres
char ** split(const char *str, const char *delim, int empty)
split the strings into a an array of char *pointer , ended by a NULL one.
int wildmat(register const char *text, register const char *p)
Written by Rich Salz rsalz at osf.org, refurbished by me.
int free_nstr_nolog(N_STR **ptr)
Free a N_STR structure and set the pointer to NULL.
int str_to_long(const char *s, long int *i, const int base)
Helper for string to integer.
int char_to_nstr_ex(const char *from, NSTRBYTE nboct, N_STR **to)
Convert a char into a N_STR, extended version.
N_STR * char_to_nstr_nocopy(char *src)
Convert a char into a N_STR, direct use of linked source pointer.
int _free_nstr(N_STR **ptr)
Free a N_STR structure and set the pointer to NULL.
int write_and_fit_ex(char **dest, NSTRBYTE *size, NSTRBYTE *written, const char *src, NSTRBYTE src_size, NSTRBYTE additional_padding)
Append src_size bytes from src to *dest, updating size/written, growing the buffer if needed.
N_STR * file_to_nstr(char *filename)
Load a whole file into a N_STR.
int free_split_result(char ***tab)
Free a split result allocated array.
N_STR * nstrprintf_ex(N_STR **nstr_var, const char *format,...)
Function to allocate and format a string into an N_STR object.
void free_nstr_ptr_nolog(void *ptr)
Free a N_STR pointer structure.
int str_to_int(const char *s, int *i, const int base)
Helper for string to integer.
int n_str_utf8_valid(const char *s, size_t len)
Test that [s, s+len) is well-formed UTF-8 (RFC 3629): no overlong form, no surrogate,...
int nstr_to_fd(N_STR *str, FILE *out, int lock)
Write a N_STR content into a file.
int str_to_long_ex(const char *s, NSTRBYTE start, NSTRBYTE end, long int *i, const int base)
Helper for string[start to end] to long integer.
int strup(const char *string, char *dest)
Upper case a string.
A box including a string and his lenght.
Common headers and low-level functions & define.
Hash functions and table.
N_STR and string function declaration.