koffi 2.14.1 → 2.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/assets.ini +2 -1
- package/doc/build.sh +9 -0
- package/doc/pages/404.md +17 -0
- package/doc/pages/index.md +5 -3
- package/doc/pages/misc.md +18 -11
- package/doc/pages.ini +4 -0
- package/doc/static/highlight.js +2 -14
- package/doc/static/koffi.css +3 -15
- package/doc/static/print.css +2 -14
- package/doc/templates/code.html +1 -2
- package/doc/templates/page.html +1 -2
- package/index.d.ts +29 -24
- package/index.js +9 -9
- package/indirect.js +9 -9
- package/{src/core → lib/native}/base/base.cc +1137 -674
- package/{src/core → lib/native}/base/base.hh +362 -195
- package/{src/core → lib/native}/base/crc.inc +2 -20
- package/lib/native/base/crc_gen.py +72 -0
- package/{src/core → lib/native}/base/mimetypes.inc +2 -20
- package/{src/core → lib/native}/base/mimetypes_gen.py +2 -21
- package/lib/native/base/tower.cc +821 -0
- package/lib/native/base/tower.hh +81 -0
- package/{src/core → lib/native}/base/unicode.inc +2 -20
- package/{src/core → lib/native}/base/unicode_gen.py +4 -41
- package/package.json +2 -2
- package/src/cnoke/assets/FindCNoke.cmake +24 -30
- package/src/cnoke/assets/win_delay_hook.c +6 -20
- package/src/cnoke/cnoke.js +2 -21
- package/src/cnoke/src/builder.js +51 -66
- package/src/cnoke/src/index.js +2 -20
- package/src/cnoke/src/tools.js +2 -20
- package/src/koffi/CMakeLists.txt +30 -23
- package/src/koffi/cmake/raylib.cmake +5 -22
- package/src/koffi/cmake/sqlite3.cmake +2 -20
- package/src/koffi/src/abi_arm32.cc +7 -25
- package/src/koffi/src/abi_arm32_asm.S +2 -20
- package/src/koffi/src/abi_arm64.cc +7 -25
- package/src/koffi/src/abi_arm64_asm.S +2 -20
- package/src/koffi/src/abi_arm64_asm.asm +2 -20
- package/src/koffi/src/abi_loong64.cc +2 -20
- package/src/koffi/src/abi_loong64_asm.S +2 -20
- package/src/koffi/src/abi_riscv64.cc +7 -25
- package/src/koffi/src/abi_riscv64_asm.S +2 -20
- package/src/koffi/src/abi_x64_sysv.cc +7 -25
- package/src/koffi/src/abi_x64_sysv_asm.S +2 -20
- package/src/koffi/src/abi_x64_win.cc +12 -30
- package/src/koffi/src/abi_x64_win_asm.S +162 -0
- package/src/koffi/src/abi_x64_win_asm.asm +2 -20
- package/src/koffi/src/abi_x86.cc +7 -25
- package/src/koffi/src/abi_x86_asm.S +2 -20
- package/src/koffi/src/abi_x86_asm.asm +2 -20
- package/src/koffi/src/call.cc +25 -45
- package/src/koffi/src/call.hh +3 -21
- package/src/koffi/src/errno.inc +2 -20
- package/src/koffi/src/ffi.cc +64 -63
- package/src/koffi/src/ffi.hh +15 -30
- package/src/koffi/src/init.js +2 -20
- package/src/koffi/src/parser.cc +13 -27
- package/src/koffi/src/parser.hh +3 -21
- package/src/koffi/src/trampolines/armasm.inc +0 -21
- package/src/koffi/src/trampolines/gnu.inc +0 -21
- package/src/koffi/src/trampolines/masm32.inc +0 -21
- package/src/koffi/src/trampolines/masm64.inc +0 -21
- package/src/koffi/src/trampolines/prototypes.inc +0 -21
- package/src/koffi/src/util.cc +50 -64
- package/src/koffi/src/util.hh +8 -25
- package/src/koffi/src/uv.cc +193 -0
- package/src/koffi/src/uv.def +10 -0
- package/src/koffi/src/uv.hh +40 -0
- package/src/koffi/src/win32.cc +2 -20
- package/src/koffi/src/win32.hh +3 -21
- package/vendor/node-api-headers/CHANGELOG.md +22 -0
- package/vendor/node-api-headers/README.md +6 -17
- package/vendor/node-api-headers/include/js_native_api.h +3 -13
- package/vendor/node-api-headers/include/js_native_api_types.h +15 -0
- package/vendor/node-api-headers/include/node_api.h +0 -4
- package/vendor/node-api-headers/include/node_api_types.h +6 -0
- package/vendor/node-api-headers/include/uv/aix.h +32 -0
- package/vendor/node-api-headers/include/uv/bsd.h +34 -0
- package/vendor/node-api-headers/include/uv/darwin.h +61 -0
- package/vendor/node-api-headers/include/uv/errno.h +483 -0
- package/vendor/node-api-headers/include/uv/linux.h +34 -0
- package/vendor/node-api-headers/include/uv/os390.h +33 -0
- package/vendor/node-api-headers/include/uv/posix.h +31 -0
- package/vendor/node-api-headers/include/uv/sunos.h +44 -0
- package/vendor/node-api-headers/include/uv/threadpool.h +37 -0
- package/vendor/node-api-headers/include/uv/tree.h +521 -0
- package/vendor/node-api-headers/include/uv/unix.h +512 -0
- package/vendor/node-api-headers/include/uv/version.h +43 -0
- package/vendor/node-api-headers/include/uv/win.h +698 -0
- package/vendor/node-api-headers/include/uv.h +1990 -0
- package/vendor/node-api-headers/package.json +1 -1
- package/vendor/node-api-headers/scripts/update-headers.js +6 -0
- package/src/core/base/crc_gen.py +0 -109
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
-
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
-
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
-
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
-
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
-
// subject to the following conditions:
|
|
9
|
-
|
|
10
|
-
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
// copies or substantial portions of the Software.
|
|
12
|
-
|
|
13
|
-
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
-
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
-
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
-
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
-
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
-
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
-
// OTHER DEALINGS IN THE SOFTWARE.
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
21
3
|
|
|
22
4
|
#pragma once
|
|
23
5
|
|
|
@@ -108,6 +90,8 @@ namespace K {
|
|
|
108
90
|
#define K_PROGRESS_USED_NODES 100
|
|
109
91
|
#define K_PROGRESS_TEXT_SIZE 64
|
|
110
92
|
|
|
93
|
+
#define K_COMPLETE_PATH_LIMIT 256
|
|
94
|
+
|
|
111
95
|
// ------------------------------------------------------------------------
|
|
112
96
|
// Utility
|
|
113
97
|
// ------------------------------------------------------------------------
|
|
@@ -1404,7 +1388,7 @@ static constexpr inline bool IsAsciiWhite(int c)
|
|
|
1404
1388
|
}
|
|
1405
1389
|
static constexpr inline bool IsAsciiControl(int c)
|
|
1406
1390
|
{
|
|
1407
|
-
return c == 0x7F || (c < ' ' && c != '\t');
|
|
1391
|
+
return c == 0x7F || ((uint8_t)c < ' ' && c != '\t');
|
|
1408
1392
|
}
|
|
1409
1393
|
|
|
1410
1394
|
static constexpr inline char UpperAscii(int c)
|
|
@@ -1584,6 +1568,47 @@ static inline bool StartsWith(const char *str, const char *prefix)
|
|
|
1584
1568
|
return !prefix[i];
|
|
1585
1569
|
}
|
|
1586
1570
|
|
|
1571
|
+
static inline bool StartsWithI(Span<const char> str, Span<const char> prefix)
|
|
1572
|
+
{
|
|
1573
|
+
Size i = 0;
|
|
1574
|
+
while (i < str.len && i < prefix.len) {
|
|
1575
|
+
if (LowerAscii(str[i]) != LowerAscii(prefix[i]))
|
|
1576
|
+
return false;
|
|
1577
|
+
i++;
|
|
1578
|
+
}
|
|
1579
|
+
return (i == prefix.len);
|
|
1580
|
+
}
|
|
1581
|
+
static inline bool StartsWithI(Span<const char> str, const char *prefix)
|
|
1582
|
+
{
|
|
1583
|
+
Size i = 0;
|
|
1584
|
+
while (i < str.len && prefix[i]) {
|
|
1585
|
+
if (LowerAscii(str[i]) != LowerAscii(prefix[i]))
|
|
1586
|
+
return false;
|
|
1587
|
+
i++;
|
|
1588
|
+
}
|
|
1589
|
+
return !prefix[i];
|
|
1590
|
+
}
|
|
1591
|
+
static inline bool StartsWithI(const char *str, Span<const char> prefix)
|
|
1592
|
+
{
|
|
1593
|
+
Size i = 0;
|
|
1594
|
+
while (str[i] && i < prefix.len) {
|
|
1595
|
+
if (LowerAscii(str[i]) != LowerAscii(prefix[i]))
|
|
1596
|
+
return false;
|
|
1597
|
+
i++;
|
|
1598
|
+
}
|
|
1599
|
+
return (i == prefix.len);
|
|
1600
|
+
}
|
|
1601
|
+
static inline bool StartsWithI(const char *str, const char *prefix)
|
|
1602
|
+
{
|
|
1603
|
+
Size i = 0;
|
|
1604
|
+
while (str[i] && prefix[i]) {
|
|
1605
|
+
if (LowerAscii(str[i]) != LowerAscii(prefix[i]))
|
|
1606
|
+
return false;
|
|
1607
|
+
i++;
|
|
1608
|
+
}
|
|
1609
|
+
return !prefix[i];
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1587
1612
|
static inline bool EndsWith(Span<const char> str, Span<const char> suffix)
|
|
1588
1613
|
{
|
|
1589
1614
|
Size i = str.len - 1;
|
|
@@ -1599,6 +1624,21 @@ static inline bool EndsWith(Span<const char> str, Span<const char> suffix)
|
|
|
1599
1624
|
|
|
1600
1625
|
return j < 0;
|
|
1601
1626
|
}
|
|
1627
|
+
static inline bool EndsWithI(Span<const char> str, Span<const char> suffix)
|
|
1628
|
+
{
|
|
1629
|
+
Size i = str.len - 1;
|
|
1630
|
+
Size j = suffix.len - 1;
|
|
1631
|
+
|
|
1632
|
+
while (i >= 0 && j >= 0) {
|
|
1633
|
+
if (LowerAscii(str[i]) != LowerAscii(suffix[j]))
|
|
1634
|
+
return false;
|
|
1635
|
+
|
|
1636
|
+
i--;
|
|
1637
|
+
j--;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
return j < 0;
|
|
1641
|
+
}
|
|
1602
1642
|
|
|
1603
1643
|
static inline Size FindStr(Span<const char> str, Span<const char> needle)
|
|
1604
1644
|
{
|
|
@@ -1902,6 +1942,9 @@ static inline Span<const char> TrimStrRight(Span<const char> str, const char *tr
|
|
|
1902
1942
|
static inline Span<const char> TrimStr(Span<const char> str, const char *trim_chars = " \t\r\n")
|
|
1903
1943
|
{ return TrimStr(MakeSpan((char *)str.ptr, str.len), trim_chars); }
|
|
1904
1944
|
|
|
1945
|
+
int CmpNatural(Span<const char> str1, Span<const char> str2);
|
|
1946
|
+
int CmpNaturalI(Span<const char> str1, Span<const char> str2);
|
|
1947
|
+
|
|
1905
1948
|
// ------------------------------------------------------------------------
|
|
1906
1949
|
// Collections
|
|
1907
1950
|
// ------------------------------------------------------------------------
|
|
@@ -2787,7 +2830,7 @@ public:
|
|
|
2787
2830
|
return ptr;
|
|
2788
2831
|
}
|
|
2789
2832
|
|
|
2790
|
-
ValueType *
|
|
2833
|
+
ValueType *InsertOrGet(const ValueType &value, bool *out_inserted = nullptr)
|
|
2791
2834
|
{
|
|
2792
2835
|
const KeyType &key = Handler::GetKey(value);
|
|
2793
2836
|
|
|
@@ -2803,7 +2846,7 @@ public:
|
|
|
2803
2846
|
}
|
|
2804
2847
|
return ptr;
|
|
2805
2848
|
}
|
|
2806
|
-
ValueType *
|
|
2849
|
+
ValueType *InsertOrGetDefault(const KeyType &key, bool *out_inserted = nullptr)
|
|
2807
2850
|
{
|
|
2808
2851
|
bool inserted;
|
|
2809
2852
|
ValueType *ptr = Insert(key, &inserted);
|
|
@@ -3247,15 +3290,15 @@ public:
|
|
|
3247
3290
|
return table_it;
|
|
3248
3291
|
}
|
|
3249
3292
|
|
|
3250
|
-
ValueType *
|
|
3293
|
+
ValueType *InsertOrGet(const KeyType &key, const ValueType &value, bool *out_inserted = nullptr)
|
|
3251
3294
|
{
|
|
3252
|
-
Bucket *ptr = table.
|
|
3295
|
+
Bucket *ptr = table.InsertOrGet({ key, value }, out_inserted);
|
|
3253
3296
|
return &ptr->value;
|
|
3254
3297
|
}
|
|
3255
|
-
Bucket *
|
|
3298
|
+
Bucket *InsertOrGetDefault(const KeyType &key, bool *out_inserted = nullptr)
|
|
3256
3299
|
{
|
|
3257
3300
|
bool inserted;
|
|
3258
|
-
Bucket *ptr = table.
|
|
3301
|
+
Bucket *ptr = table.InsertOrGetDefault(key, &inserted);
|
|
3259
3302
|
|
|
3260
3303
|
if (inserted) {
|
|
3261
3304
|
ptr->key = key;
|
|
@@ -3318,14 +3361,23 @@ public:
|
|
|
3318
3361
|
{ return table.FindValue(value, default_value); }
|
|
3319
3362
|
|
|
3320
3363
|
ValueType *Set(const ValueType &value) { return table.Set(value); }
|
|
3321
|
-
|
|
3322
|
-
|
|
3364
|
+
|
|
3365
|
+
ValueType *InsertOrGet(const ValueType &value, bool *out_inserted = nullptr)
|
|
3366
|
+
{ return table.InsertOrGet(value, out_inserted); }
|
|
3367
|
+
bool InsertOrFail(const ValueType &value)
|
|
3368
|
+
{
|
|
3369
|
+
bool inserted;
|
|
3370
|
+
InsertOrGet(value, &inserted);
|
|
3371
|
+
return inserted;
|
|
3372
|
+
}
|
|
3323
3373
|
|
|
3324
3374
|
void Remove(ValueType *it) { table.Remove(it); }
|
|
3325
3375
|
template <typename T = ValueType>
|
|
3326
3376
|
void Remove(const T &value) { Remove(Find(value)); }
|
|
3327
3377
|
|
|
3328
3378
|
void Trim() { table.Trim(); }
|
|
3379
|
+
|
|
3380
|
+
private:
|
|
3329
3381
|
};
|
|
3330
3382
|
|
|
3331
3383
|
// XXX: Switch to perfect hashing later on
|
|
@@ -3343,7 +3395,7 @@ public:
|
|
|
3343
3395
|
|
|
3344
3396
|
constexpr ConstMap(std::initializer_list<Bucket> l)
|
|
3345
3397
|
{
|
|
3346
|
-
K_CRITICAL(l.size() <= N, "ConstMap<%1> cannot
|
|
3398
|
+
K_CRITICAL(l.size() <= N, "ConstMap<%1> cannot store %2 values", N, l.size());
|
|
3347
3399
|
|
|
3348
3400
|
for (const Bucket &it: l) {
|
|
3349
3401
|
Bucket *bucket = Insert(it.key);
|
|
@@ -3352,14 +3404,6 @@ public:
|
|
|
3352
3404
|
bucket->value = it.value;
|
|
3353
3405
|
}
|
|
3354
3406
|
}
|
|
3355
|
-
~ConstMap()
|
|
3356
|
-
{
|
|
3357
|
-
if constexpr(!std::is_trivial<ValueType>::value) {
|
|
3358
|
-
for (Size i = 0; i < N; i++) {
|
|
3359
|
-
data[i].~ValueType();
|
|
3360
|
-
}
|
|
3361
|
-
}
|
|
3362
|
-
}
|
|
3363
3407
|
|
|
3364
3408
|
template <typename T = KeyType>
|
|
3365
3409
|
ValueType *Find(const T &key)
|
|
@@ -3535,24 +3579,6 @@ union LocalDate {
|
|
|
3535
3579
|
// ------------------------------------------------------------------------
|
|
3536
3580
|
|
|
3537
3581
|
int64_t GetUnixTime();
|
|
3538
|
-
int64_t GetMonotonicTime();
|
|
3539
|
-
|
|
3540
|
-
#if defined(_MSC_VER) && !defined(_M_ARM64)
|
|
3541
|
-
static inline int64_t GetClockCounter()
|
|
3542
|
-
{
|
|
3543
|
-
return (int64_t)__rdtsc();
|
|
3544
|
-
}
|
|
3545
|
-
#elif defined(__i386__) || defined(__x86_64__)
|
|
3546
|
-
static inline int64_t GetClockCounter()
|
|
3547
|
-
{
|
|
3548
|
-
uint32_t counter_low, counter_high;
|
|
3549
|
-
__asm__ __volatile__ ("cpuid; rdtsc"
|
|
3550
|
-
: "=a" (counter_low), "=d" (counter_high)
|
|
3551
|
-
: : "%ebx", "%ecx");
|
|
3552
|
-
int64_t counter = ((int64_t)counter_high << 32) | counter_low;
|
|
3553
|
-
return counter;
|
|
3554
|
-
}
|
|
3555
|
-
#endif
|
|
3556
3582
|
|
|
3557
3583
|
struct TimeSpec {
|
|
3558
3584
|
int16_t year;
|
|
@@ -3572,15 +3598,46 @@ TimeSpec DecomposeTimeUTC(int64_t time);
|
|
|
3572
3598
|
TimeSpec DecomposeTimeLocal(int64_t time);
|
|
3573
3599
|
int64_t ComposeTimeUTC(const TimeSpec &spec);
|
|
3574
3600
|
|
|
3601
|
+
// ------------------------------------------------------------------------
|
|
3602
|
+
// Clock
|
|
3603
|
+
// ------------------------------------------------------------------------
|
|
3604
|
+
|
|
3605
|
+
#if defined(_MSC_VER) && !defined(_M_ARM64)
|
|
3606
|
+
static inline int64_t GetCoreCycles()
|
|
3607
|
+
{
|
|
3608
|
+
return (int64_t)__rdtsc();
|
|
3609
|
+
}
|
|
3610
|
+
#elif defined(__i386__) || defined(__x86_64__)
|
|
3611
|
+
static inline int64_t GetCoreCycles()
|
|
3612
|
+
{
|
|
3613
|
+
uint32_t counter_low, counter_high;
|
|
3614
|
+
__asm__ __volatile__ ("cpuid; rdtsc"
|
|
3615
|
+
: "=a" (counter_low), "=d" (counter_high)
|
|
3616
|
+
: : "%ebx", "%ecx");
|
|
3617
|
+
int64_t counter = ((int64_t)counter_high << 32) | counter_low;
|
|
3618
|
+
return counter;
|
|
3619
|
+
}
|
|
3620
|
+
#elif defined(__aarch64__)
|
|
3621
|
+
static inline int64_t GetCoreCycles()
|
|
3622
|
+
{
|
|
3623
|
+
uint64_t counter;
|
|
3624
|
+
__asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (counter));
|
|
3625
|
+
return counter;
|
|
3626
|
+
}
|
|
3627
|
+
#endif
|
|
3628
|
+
|
|
3629
|
+
int64_t GetMonotonicClock();
|
|
3630
|
+
|
|
3575
3631
|
// ------------------------------------------------------------------------
|
|
3576
3632
|
// Format
|
|
3577
3633
|
// ------------------------------------------------------------------------
|
|
3578
3634
|
|
|
3579
3635
|
enum class FmtType {
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3636
|
+
Str,
|
|
3637
|
+
PadStr,
|
|
3638
|
+
RepeatStr,
|
|
3583
3639
|
Char,
|
|
3640
|
+
Buffer,
|
|
3584
3641
|
Custom,
|
|
3585
3642
|
Bool,
|
|
3586
3643
|
Integer,
|
|
@@ -3591,15 +3648,19 @@ enum class FmtType {
|
|
|
3591
3648
|
Octal,
|
|
3592
3649
|
BigHex,
|
|
3593
3650
|
SmallHex,
|
|
3651
|
+
BigBytes,
|
|
3652
|
+
SmallBytes,
|
|
3594
3653
|
MemorySize,
|
|
3595
3654
|
DiskSize,
|
|
3596
3655
|
Date,
|
|
3597
3656
|
TimeISO,
|
|
3598
3657
|
TimeNice,
|
|
3599
|
-
|
|
3658
|
+
List,
|
|
3600
3659
|
FlagNames,
|
|
3601
3660
|
FlagOptions,
|
|
3602
|
-
|
|
3661
|
+
Random,
|
|
3662
|
+
SafeStr,
|
|
3663
|
+
SafeChar
|
|
3603
3664
|
};
|
|
3604
3665
|
|
|
3605
3666
|
template <typename T>
|
|
@@ -3649,14 +3710,18 @@ class FmtArg {
|
|
|
3649
3710
|
public:
|
|
3650
3711
|
FmtType type;
|
|
3651
3712
|
union {
|
|
3652
|
-
const char
|
|
3653
|
-
|
|
3713
|
+
Span<const char> str;
|
|
3714
|
+
struct {
|
|
3715
|
+
const char *str;
|
|
3716
|
+
int count;
|
|
3717
|
+
} repeat;
|
|
3654
3718
|
char buf[32];
|
|
3655
3719
|
char ch;
|
|
3656
3720
|
FmtCustom custom;
|
|
3657
3721
|
bool b;
|
|
3658
3722
|
int64_t i;
|
|
3659
3723
|
uint64_t u;
|
|
3724
|
+
Span<const uint8_t> hex;
|
|
3660
3725
|
struct {
|
|
3661
3726
|
float value;
|
|
3662
3727
|
int min_prec;
|
|
@@ -3684,68 +3749,123 @@ public:
|
|
|
3684
3749
|
Span<const struct OptionDesc> options;
|
|
3685
3750
|
} u;
|
|
3686
3751
|
const char *separator;
|
|
3687
|
-
}
|
|
3688
|
-
|
|
3689
|
-
struct {
|
|
3690
|
-
FmtType type;
|
|
3691
|
-
int type_len;
|
|
3692
|
-
const void *ptr;
|
|
3693
|
-
Size len;
|
|
3694
|
-
const char *separator;
|
|
3695
|
-
} span;
|
|
3752
|
+
} list;
|
|
3696
3753
|
} u;
|
|
3697
3754
|
|
|
3698
|
-
int
|
|
3699
|
-
|
|
3700
|
-
char pad_char = 0;
|
|
3755
|
+
int pad = 0;
|
|
3756
|
+
char padding = 0;
|
|
3701
3757
|
|
|
3702
3758
|
FmtArg() = default;
|
|
3703
|
-
FmtArg(
|
|
3704
|
-
FmtArg(
|
|
3705
|
-
FmtArg(
|
|
3706
|
-
FmtArg(char
|
|
3707
|
-
FmtArg(
|
|
3708
|
-
FmtArg(
|
|
3709
|
-
FmtArg(
|
|
3710
|
-
FmtArg(
|
|
3711
|
-
FmtArg(
|
|
3712
|
-
FmtArg(
|
|
3713
|
-
FmtArg(
|
|
3714
|
-
FmtArg(
|
|
3715
|
-
FmtArg(
|
|
3716
|
-
FmtArg(
|
|
3717
|
-
FmtArg(
|
|
3718
|
-
FmtArg(
|
|
3719
|
-
FmtArg(
|
|
3720
|
-
FmtArg(
|
|
3721
|
-
FmtArg(const
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
FmtArg
|
|
3759
|
+
FmtArg(const FmtArg &other) = default;
|
|
3760
|
+
FmtArg(std::nullptr_t) : FmtArg(FmtType::Str) { u.str = "(null)"; }
|
|
3761
|
+
FmtArg(const char *str) : FmtArg(FmtType::Str) { u.str = str ? str : "(null)"; }
|
|
3762
|
+
FmtArg(Span<const char> str) : FmtArg(FmtType::Str) { u.str = str; }
|
|
3763
|
+
FmtArg(char c) : FmtArg(FmtType::Char) { u.ch = c; }
|
|
3764
|
+
FmtArg(const FmtCustom &custom) : FmtArg(FmtType::Custom) { u.custom = custom; }
|
|
3765
|
+
FmtArg(bool b) : FmtArg(FmtType::Bool) { u.b = b; }
|
|
3766
|
+
FmtArg(unsigned char i) : FmtArg(FmtType::Unsigned) { u.u = i; }
|
|
3767
|
+
FmtArg(short i) : FmtArg(FmtType::Integer) { u.i = i; }
|
|
3768
|
+
FmtArg(unsigned short i) : FmtArg(FmtType::Unsigned) { u.u = i; }
|
|
3769
|
+
FmtArg(int i) : FmtArg(FmtType::Integer) { u.i = i; }
|
|
3770
|
+
FmtArg(unsigned int i) : FmtArg(FmtType::Unsigned) { u.u = i; }
|
|
3771
|
+
FmtArg(long i) : FmtArg(FmtType::Integer) { u.i = i; }
|
|
3772
|
+
FmtArg(unsigned long i) : FmtArg(FmtType::Unsigned) { u.u = i; }
|
|
3773
|
+
FmtArg(long long i) : FmtArg(FmtType::Integer) { u.i = i; }
|
|
3774
|
+
FmtArg(unsigned long long i) : FmtArg(FmtType::Unsigned) { u.u = i; }
|
|
3775
|
+
FmtArg(float f) : FmtArg(FmtType::Float) { u.f = { f, 0, INT_MAX }; }
|
|
3776
|
+
FmtArg(double d) : FmtArg(FmtType::Double) { u.d = { d, 0, INT_MAX }; }
|
|
3777
|
+
FmtArg(const void *ptr) : FmtArg(FmtType::BigHex) { u.u = (uint64_t)ptr; }
|
|
3778
|
+
FmtArg(const LocalDate &date) : FmtArg(FmtType::Date) { u.date = date; }
|
|
3779
|
+
|
|
3780
|
+
protected:
|
|
3781
|
+
FmtArg(FmtType type) : type(type) {}
|
|
3782
|
+
};
|
|
3783
|
+
|
|
3784
|
+
class FmtSafe: public FmtArg {
|
|
3785
|
+
public:
|
|
3786
|
+
FmtSafe() = default;
|
|
3787
|
+
FmtSafe(FmtArg arg) : FmtArg(arg) {}
|
|
3788
|
+
FmtSafe(std::nullptr_t) : FmtArg(FmtType::Str) { u.str = "(null)"; }
|
|
3789
|
+
FmtSafe(const char *str) : FmtArg(FmtType::SafeStr) { u.str = str ? str : "(null)"; } // safe
|
|
3790
|
+
FmtSafe(Span<const char> str) : FmtArg(FmtType::SafeStr) { u.str = str; } // safe
|
|
3791
|
+
FmtSafe(char c) : FmtArg(FmtType::SafeChar) { u.ch = c; } // safe
|
|
3792
|
+
FmtSafe(const FmtCustom &custom) : FmtArg(custom) {}
|
|
3793
|
+
FmtSafe(bool b) : FmtArg(b) {}
|
|
3794
|
+
FmtSafe(unsigned char i) : FmtArg(i) {}
|
|
3795
|
+
FmtSafe(short i) : FmtArg(i) {}
|
|
3796
|
+
FmtSafe(unsigned short i) : FmtArg(i) {}
|
|
3797
|
+
FmtSafe(int i) : FmtArg(i) {}
|
|
3798
|
+
FmtSafe(unsigned int i) : FmtArg(i) {}
|
|
3799
|
+
FmtSafe(long i) : FmtArg(i) {}
|
|
3800
|
+
FmtSafe(unsigned long i) : FmtArg(i) {}
|
|
3801
|
+
FmtSafe(long long i) : FmtArg(i) {}
|
|
3802
|
+
FmtSafe(unsigned long long i) : FmtArg(i) {}
|
|
3803
|
+
FmtSafe(float f) : FmtArg(f) {}
|
|
3804
|
+
FmtSafe(double d) : FmtArg(d) {}
|
|
3805
|
+
FmtSafe(const void *ptr) : FmtArg(ptr) {}
|
|
3806
|
+
FmtSafe(const LocalDate &date) : FmtArg(date) {}
|
|
3726
3807
|
};
|
|
3727
3808
|
|
|
3728
|
-
static inline FmtArg
|
|
3809
|
+
static inline FmtArg FmtInt(long long i, int pad = 0, char padding = '0')
|
|
3810
|
+
{
|
|
3811
|
+
FmtArg arg;
|
|
3812
|
+
arg.type = FmtType::Integer;
|
|
3813
|
+
arg.u.i = i;
|
|
3814
|
+
arg.pad = pad;
|
|
3815
|
+
arg.padding = padding;
|
|
3816
|
+
return arg;
|
|
3817
|
+
}
|
|
3818
|
+
static inline FmtArg FmtInt(unsigned long long u, int pad = 0, char padding = '0')
|
|
3819
|
+
{
|
|
3820
|
+
FmtArg arg;
|
|
3821
|
+
arg.type = FmtType::Unsigned;
|
|
3822
|
+
arg.u.u = u;
|
|
3823
|
+
arg.pad = pad;
|
|
3824
|
+
arg.padding = padding;
|
|
3825
|
+
return arg;
|
|
3826
|
+
}
|
|
3827
|
+
static inline FmtArg FmtInt(unsigned char u, int pad = 0, char padding = '0') { return FmtInt((unsigned long long)u, pad, padding); }
|
|
3828
|
+
static inline FmtArg FmtInt(short i, int pad = 0, char padding = '0') { return FmtInt((long long)i, pad, padding); }
|
|
3829
|
+
static inline FmtArg FmtInt(unsigned short u, int pad = 0, char padding = '0') { return FmtInt((unsigned long long)u, pad, padding); }
|
|
3830
|
+
static inline FmtArg FmtInt(int i, int pad = 0, char padding = '0') { return FmtInt((long long)i, pad, padding); }
|
|
3831
|
+
static inline FmtArg FmtInt(unsigned int u, int pad = 0, char padding = '0') { return FmtInt((unsigned long long)u, pad, padding); }
|
|
3832
|
+
static inline FmtArg FmtInt(long i, int pad = 0, char padding = '0') { return FmtInt((long long)i, pad, padding); }
|
|
3833
|
+
static inline FmtArg FmtInt(unsigned long u, int pad = 0, char padding = '0') { return FmtInt((unsigned long long)u, pad, padding); }
|
|
3834
|
+
|
|
3835
|
+
static inline FmtArg FmtBin(uint64_t u, int pad = 0, char padding = '0')
|
|
3729
3836
|
{
|
|
3730
3837
|
FmtArg arg;
|
|
3731
3838
|
arg.type = FmtType::Binary;
|
|
3732
3839
|
arg.u.u = u;
|
|
3840
|
+
arg.pad = pad;
|
|
3841
|
+
arg.padding = padding;
|
|
3733
3842
|
return arg;
|
|
3734
3843
|
}
|
|
3735
|
-
static inline FmtArg FmtOctal(uint64_t u)
|
|
3844
|
+
static inline FmtArg FmtOctal(uint64_t u, int pad = 0, char padding = '0')
|
|
3736
3845
|
{
|
|
3737
3846
|
FmtArg arg;
|
|
3738
3847
|
arg.type = FmtType::Octal;
|
|
3739
3848
|
arg.u.u = u;
|
|
3849
|
+
arg.pad = pad;
|
|
3850
|
+
arg.padding = padding;
|
|
3740
3851
|
return arg;
|
|
3741
3852
|
}
|
|
3742
|
-
static inline FmtArg FmtHex(uint64_t u,
|
|
3853
|
+
static inline FmtArg FmtHex(uint64_t u, int pad = 0, char padding = '0')
|
|
3743
3854
|
{
|
|
3744
|
-
K_ASSERT(type == FmtType::BigHex || type == FmtType::SmallHex);
|
|
3745
|
-
|
|
3746
3855
|
FmtArg arg;
|
|
3747
|
-
arg.type =
|
|
3856
|
+
arg.type = FmtType::BigHex;
|
|
3748
3857
|
arg.u.u = u;
|
|
3858
|
+
arg.pad = pad;
|
|
3859
|
+
arg.padding = padding;
|
|
3860
|
+
return arg;
|
|
3861
|
+
}
|
|
3862
|
+
static inline FmtArg FmtHexSmall(uint64_t u, int pad = 0, char padding = '0')
|
|
3863
|
+
{
|
|
3864
|
+
FmtArg arg;
|
|
3865
|
+
arg.type = FmtType::SmallHex;
|
|
3866
|
+
arg.u.u = u;
|
|
3867
|
+
arg.pad = pad;
|
|
3868
|
+
arg.padding = padding;
|
|
3749
3869
|
return arg;
|
|
3750
3870
|
}
|
|
3751
3871
|
|
|
@@ -3806,61 +3926,76 @@ static inline FmtArg FmtTimeNice(TimeSpec spec, bool ms = false)
|
|
|
3806
3926
|
return arg;
|
|
3807
3927
|
}
|
|
3808
3928
|
|
|
3809
|
-
static inline FmtArg
|
|
3929
|
+
static inline FmtArg FmtList(Span<const char *const> names, const char *sep = ", ")
|
|
3810
3930
|
{
|
|
3811
|
-
K_ASSERT(len < 256);
|
|
3812
|
-
len = std::min(len, (Size)256);
|
|
3813
|
-
|
|
3814
3931
|
FmtArg arg;
|
|
3815
|
-
arg.type = FmtType::
|
|
3816
|
-
arg.u.
|
|
3817
|
-
arg.u.
|
|
3932
|
+
arg.type = FmtType::List;
|
|
3933
|
+
arg.u.list.u.names = names;
|
|
3934
|
+
arg.u.list.separator = sep;
|
|
3818
3935
|
return arg;
|
|
3819
3936
|
}
|
|
3820
|
-
|
|
3821
3937
|
static inline FmtArg FmtFlags(uint64_t flags, Span<const char *const> names, const char *sep = ", ")
|
|
3822
3938
|
{
|
|
3823
3939
|
FmtArg arg;
|
|
3824
3940
|
arg.type = FmtType::FlagNames;
|
|
3825
|
-
arg.u.
|
|
3826
|
-
arg.u.
|
|
3827
|
-
arg.u.
|
|
3941
|
+
arg.u.list.flags = flags & ((1ull << names.len) - 1);
|
|
3942
|
+
arg.u.list.u.names = names;
|
|
3943
|
+
arg.u.list.separator = sep;
|
|
3828
3944
|
return arg;
|
|
3829
3945
|
}
|
|
3830
|
-
|
|
3831
3946
|
static inline FmtArg FmtFlags(uint64_t flags, Span<const struct OptionDesc> options, const char *sep = ", ")
|
|
3832
3947
|
{
|
|
3833
3948
|
FmtArg arg;
|
|
3834
3949
|
arg.type = FmtType::FlagOptions;
|
|
3835
|
-
arg.u.
|
|
3836
|
-
arg.u.
|
|
3837
|
-
arg.u.
|
|
3950
|
+
arg.u.list.flags = flags & ((1ull << options.len) - 1);
|
|
3951
|
+
arg.u.list.u.options = options;
|
|
3952
|
+
arg.u.list.separator = sep;
|
|
3838
3953
|
return arg;
|
|
3839
3954
|
}
|
|
3840
3955
|
|
|
3841
|
-
|
|
3842
|
-
FmtArg FmtSpan(Span<T> arr, FmtType type, const char *sep = ", ")
|
|
3956
|
+
static inline FmtArg FmtPad(Span<const char> str, int pad, char padding = ' ')
|
|
3843
3957
|
{
|
|
3844
3958
|
FmtArg arg;
|
|
3845
|
-
arg.type = FmtType::
|
|
3846
|
-
arg.u.
|
|
3847
|
-
arg.
|
|
3848
|
-
arg.
|
|
3849
|
-
arg
|
|
3850
|
-
|
|
3959
|
+
arg.type = FmtType::PadStr;
|
|
3960
|
+
arg.u.str = str;
|
|
3961
|
+
arg.pad = pad;
|
|
3962
|
+
arg.padding = padding;
|
|
3963
|
+
return arg;
|
|
3964
|
+
}
|
|
3965
|
+
static inline FmtArg FmtRepeat(const char *str, int count)
|
|
3966
|
+
{
|
|
3967
|
+
FmtArg arg;
|
|
3968
|
+
arg.type = FmtType::RepeatStr;
|
|
3969
|
+
arg.u.repeat.str = str;
|
|
3970
|
+
arg.u.repeat.count = count;
|
|
3851
3971
|
return arg;
|
|
3852
3972
|
}
|
|
3853
|
-
template <typename T>
|
|
3854
|
-
FmtArg FmtSpan(Span<T> arr, const char *sep = ", ") { return FmtSpan(arr, FmtArg(T()).type, sep); }
|
|
3855
|
-
template <typename T, Size N>
|
|
3856
|
-
FmtArg FmtSpan(T (&arr)[N], FmtType type, const char *sep = ", ") { return FmtSpan(MakeSpan(arr), type, sep); }
|
|
3857
|
-
template <typename T, Size N>
|
|
3858
|
-
FmtArg FmtSpan(T (&arr)[N], const char *sep = ", ") { return FmtSpan(MakeSpan(arr), sep); }
|
|
3859
3973
|
|
|
3860
|
-
static inline FmtArg FmtHex(Span<const uint8_t> buf
|
|
3974
|
+
static inline FmtArg FmtHex(Span<const uint8_t> buf)
|
|
3861
3975
|
{
|
|
3862
|
-
|
|
3863
|
-
|
|
3976
|
+
FmtArg arg;
|
|
3977
|
+
arg.type = FmtType::BigBytes;
|
|
3978
|
+
arg.u.hex = buf;
|
|
3979
|
+
return arg;
|
|
3980
|
+
}
|
|
3981
|
+
static inline FmtArg FmtHexSmall(Span<const uint8_t> buf)
|
|
3982
|
+
{
|
|
3983
|
+
FmtArg arg;
|
|
3984
|
+
arg.type = FmtType::SmallBytes;
|
|
3985
|
+
arg.u.hex = buf;
|
|
3986
|
+
return arg;
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3989
|
+
static inline FmtArg FmtRandom(Size len, const char *chars = nullptr)
|
|
3990
|
+
{
|
|
3991
|
+
K_ASSERT(len < 256);
|
|
3992
|
+
len = std::min(len, (Size)256);
|
|
3993
|
+
|
|
3994
|
+
FmtArg arg;
|
|
3995
|
+
arg.type = FmtType::Random;
|
|
3996
|
+
arg.u.random.len = len;
|
|
3997
|
+
arg.u.random.chars = chars;
|
|
3998
|
+
return arg;
|
|
3864
3999
|
}
|
|
3865
4000
|
|
|
3866
4001
|
class FmtUpperAscii {
|
|
@@ -3883,23 +4018,34 @@ public:
|
|
|
3883
4018
|
operator FmtArg() const { return FmtCustom(*this); }
|
|
3884
4019
|
};
|
|
3885
4020
|
|
|
3886
|
-
class
|
|
4021
|
+
class FmtUrlSafe {
|
|
3887
4022
|
Span<const char> str;
|
|
4023
|
+
const char *passthrough;
|
|
3888
4024
|
|
|
3889
4025
|
public:
|
|
3890
|
-
|
|
4026
|
+
FmtUrlSafe(Span<const char> str, const char *passthrough)
|
|
4027
|
+
: str(str), passthrough(passthrough) {}
|
|
3891
4028
|
|
|
3892
4029
|
void Format(FunctionRef<void(Span<const char>)> append) const;
|
|
3893
4030
|
operator FmtArg() const { return FmtCustom(*this); }
|
|
3894
4031
|
};
|
|
3895
4032
|
|
|
3896
|
-
class
|
|
4033
|
+
class FmtHtmlSafe {
|
|
3897
4034
|
Span<const char> str;
|
|
3898
|
-
const char *passthrough;
|
|
3899
4035
|
|
|
3900
4036
|
public:
|
|
3901
|
-
|
|
3902
|
-
|
|
4037
|
+
FmtHtmlSafe(Span<const char> str) : str(str) {}
|
|
4038
|
+
|
|
4039
|
+
void Format(FunctionRef<void(Span<const char>)> append) const;
|
|
4040
|
+
operator FmtArg() const { return FmtCustom(*this); }
|
|
4041
|
+
};
|
|
4042
|
+
|
|
4043
|
+
class FmtEscape {
|
|
4044
|
+
Span<const char> str;
|
|
4045
|
+
char quote;
|
|
4046
|
+
|
|
4047
|
+
public:
|
|
4048
|
+
FmtEscape(Span<const char> str, char quote) : str(str), quote(quote) {}
|
|
3903
4049
|
|
|
3904
4050
|
void Format(FunctionRef<void(Span<const char>)> append) const;
|
|
3905
4051
|
operator FmtArg() const { return FmtCustom(*this); }
|
|
@@ -4004,7 +4150,7 @@ static inline void Log(LogLevel level, const char *ctx, const char *fmt)
|
|
|
4004
4150
|
template <typename... Args>
|
|
4005
4151
|
static inline void Log(LogLevel level, const char *ctx, const char *fmt, Args... args)
|
|
4006
4152
|
{
|
|
4007
|
-
const FmtArg fmt_args[] = {
|
|
4153
|
+
const FmtArg fmt_args[] = { FmtSafe(args)... };
|
|
4008
4154
|
LogFmt(level, ctx, fmt, fmt_args);
|
|
4009
4155
|
}
|
|
4010
4156
|
|
|
@@ -4215,11 +4361,11 @@ static const char *const CompressionTypeExtensions[] = {
|
|
|
4215
4361
|
Span<const char> GetPathDirectory(Span<const char> filename);
|
|
4216
4362
|
Span<const char> GetPathExtension(Span<const char> filename,
|
|
4217
4363
|
CompressionType *out_compression_type = nullptr);
|
|
4218
|
-
CompressionType GetPathCompression(Span<const char> filename);
|
|
4219
4364
|
|
|
4220
4365
|
enum class NormalizeFlag {
|
|
4221
4366
|
EndWithSeparator = 1 << 0,
|
|
4222
|
-
ForceSlash = 1 << 1
|
|
4367
|
+
ForceSlash = 1 << 1,
|
|
4368
|
+
NoExpansion = 1 << 2
|
|
4223
4369
|
};
|
|
4224
4370
|
|
|
4225
4371
|
Span<char> NormalizePath(Span<const char> path, Span<const char> root_directory, unsigned int flags, Allocator *alloc);
|
|
@@ -4233,6 +4379,7 @@ static inline Span<char> NormalizePath(Span<const char> path, Allocator *alloc)
|
|
|
4233
4379
|
bool PathIsAbsolute(const char *path);
|
|
4234
4380
|
bool PathIsAbsolute(Span<const char> path);
|
|
4235
4381
|
bool PathContainsDotDot(const char *path);
|
|
4382
|
+
bool PathContainsDotDot(Span<const char> path);
|
|
4236
4383
|
|
|
4237
4384
|
enum class StatFlag {
|
|
4238
4385
|
SilentMissing = 1 << 0,
|
|
@@ -4305,7 +4452,20 @@ static inline RenameResult RenameFile(const char *src_filename, const char *dest
|
|
|
4305
4452
|
{ return RenameFile(src_filename, dest_filename, 0, flags); }
|
|
4306
4453
|
|
|
4307
4454
|
bool ResizeFile(int fd, const char *filename, int64_t len);
|
|
4308
|
-
|
|
4455
|
+
|
|
4456
|
+
#if !defined(_WIN32)
|
|
4457
|
+
bool SetFileMode(int fd, const char *filename, uint32_t mode);
|
|
4458
|
+
static inline bool SetFileMode(const char *filename, uint32_t mode)
|
|
4459
|
+
{ return SetFileMode(-1, filename, mode); }
|
|
4460
|
+
|
|
4461
|
+
bool SetFileOwner(int fd, const char *filename, uint32_t uid, uint32_t gid);
|
|
4462
|
+
static inline bool SetFileOwner(const char *filename, uint32_t uid, uint32_t gid)
|
|
4463
|
+
{ return SetFileOwner(-1, filename, uid, gid); }
|
|
4464
|
+
#endif
|
|
4465
|
+
|
|
4466
|
+
bool SetFileTimes(int fd, const char *filename, int64_t mtime, int64_t ctime);
|
|
4467
|
+
static inline bool SetFileTimes(const char *filename, int64_t mtime, int64_t ctime)
|
|
4468
|
+
{ return SetFileTimes(-1, filename, mtime, ctime); }
|
|
4309
4469
|
|
|
4310
4470
|
struct VolumeInfo {
|
|
4311
4471
|
int64_t total;
|
|
@@ -4430,7 +4590,7 @@ void CloseHandleSafe(void **handle_ptr); // HANDLE
|
|
|
4430
4590
|
#else
|
|
4431
4591
|
void SetSignalHandler(int signal, void (*func)(int), struct sigaction *prev = nullptr);
|
|
4432
4592
|
|
|
4433
|
-
bool CreatePipe(int
|
|
4593
|
+
bool CreatePipe(bool block, int out_pfd[2]);
|
|
4434
4594
|
void CloseDescriptorSafe(int *fd_ptr);
|
|
4435
4595
|
#endif
|
|
4436
4596
|
|
|
@@ -4454,7 +4614,7 @@ bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
|
4454
4614
|
HeapArray<uint8_t> *out_buf, int *out_code);
|
|
4455
4615
|
|
|
4456
4616
|
// Simple variants
|
|
4457
|
-
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,int *out_code)
|
|
4617
|
+
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info, int *out_code)
|
|
4458
4618
|
{ return ExecuteCommandLine(cmd_line, info, {}, {}, out_code); }
|
|
4459
4619
|
static inline bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
4460
4620
|
Span<const uint8_t> in_buf,
|
|
@@ -4499,35 +4659,29 @@ enum class WaitResult {
|
|
|
4499
4659
|
Timeout,
|
|
4500
4660
|
Interrupt,
|
|
4501
4661
|
Message,
|
|
4502
|
-
Exit
|
|
4503
|
-
Error
|
|
4662
|
+
Exit
|
|
4504
4663
|
};
|
|
4505
4664
|
|
|
4506
|
-
#if defined(_WIN32)
|
|
4507
|
-
typedef void * WaitHandle; // HANDLE
|
|
4508
|
-
#else
|
|
4509
|
-
typedef int WaitHandle;
|
|
4510
|
-
#endif
|
|
4511
|
-
|
|
4512
4665
|
struct WaitSource {
|
|
4513
4666
|
#if defined(_WIN32)
|
|
4514
4667
|
// Special-cased on Windows: set to NULL to wait for the Win32 message pump too
|
|
4515
4668
|
void *handle; // HANDLE
|
|
4669
|
+
int timeout;
|
|
4516
4670
|
#else
|
|
4517
4671
|
int fd;
|
|
4518
|
-
int events;
|
|
4519
|
-
#endif
|
|
4520
|
-
|
|
4521
4672
|
int timeout;
|
|
4673
|
+
int events = 0;
|
|
4674
|
+
#endif
|
|
4522
4675
|
};
|
|
4523
4676
|
|
|
4524
4677
|
// After WaitEvents() has been called once (even with timeout 0), a few signals (such as SIGINT, SIGHUP)
|
|
4525
4678
|
// and their Windows equivalent will be permanently ignored.
|
|
4526
|
-
//
|
|
4679
|
+
// Only the main thread (running main) will get WaitResult::Message events (and SIGUSR1).
|
|
4527
4680
|
WaitResult WaitEvents(Span<const WaitSource> sources, int64_t timeout, uint64_t *out_ready = nullptr);
|
|
4528
4681
|
WaitResult WaitEvents(int64_t timeout);
|
|
4529
4682
|
|
|
4530
|
-
void
|
|
4683
|
+
void PostWaitMessage();
|
|
4684
|
+
void PostTerminate();
|
|
4531
4685
|
|
|
4532
4686
|
#endif
|
|
4533
4687
|
|
|
@@ -4833,12 +4987,10 @@ bool InitWinsock();
|
|
|
4833
4987
|
|
|
4834
4988
|
int CreateSocket(SocketType type, int flags);
|
|
4835
4989
|
|
|
4836
|
-
bool BindIPSocket(int sock, SocketType type, int port);
|
|
4990
|
+
bool BindIPSocket(int sock, SocketType type, const char *addr, int port);
|
|
4837
4991
|
bool BindUnixSocket(int sock, const char *path);
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
int OpenUnixSocket(const char *path, int flags);
|
|
4841
|
-
int ConnectToUnixSocket(const char *path, int flags);
|
|
4992
|
+
bool ConnectIPSocket(int sock, const char *addr, int port);
|
|
4993
|
+
bool ConnectUnixSocket(int sock, const char *path);
|
|
4842
4994
|
|
|
4843
4995
|
// Only for sockets on Windows
|
|
4844
4996
|
void SetDescriptorNonBlock(int fd, bool enable);
|
|
@@ -4898,10 +5050,6 @@ enum class CompressionSpeed {
|
|
|
4898
5050
|
class StreamDecoder;
|
|
4899
5051
|
class StreamEncoder;
|
|
4900
5052
|
|
|
4901
|
-
enum class StreamReaderFlag {
|
|
4902
|
-
LazyFill = 1 << 0
|
|
4903
|
-
};
|
|
4904
|
-
|
|
4905
5053
|
class StreamReader {
|
|
4906
5054
|
K_DELETE_COPY(StreamReader)
|
|
4907
5055
|
|
|
@@ -4912,7 +5060,6 @@ class StreamReader {
|
|
|
4912
5060
|
};
|
|
4913
5061
|
|
|
4914
5062
|
const char *filename = nullptr;
|
|
4915
|
-
bool lazy = false;
|
|
4916
5063
|
bool error = true;
|
|
4917
5064
|
|
|
4918
5065
|
int64_t read_total = 0;
|
|
@@ -4952,30 +5099,24 @@ class StreamReader {
|
|
|
4952
5099
|
|
|
4953
5100
|
public:
|
|
4954
5101
|
StreamReader() { Close(true); }
|
|
4955
|
-
StreamReader(Span<const uint8_t> buf, const char *filename,
|
|
5102
|
+
StreamReader(Span<const uint8_t> buf, const char *filename, CompressionType compression_type = CompressionType::None)
|
|
5103
|
+
: StreamReader() { Open(buf, filename, compression_type); }
|
|
5104
|
+
StreamReader(int fd, const char *filename, CompressionType compression_type = CompressionType::None)
|
|
5105
|
+
: StreamReader() { Open(fd, filename, compression_type); }
|
|
5106
|
+
StreamReader(const char *filename, CompressionType compression_type = CompressionType::None)
|
|
5107
|
+
: StreamReader() { Open(filename, compression_type); }
|
|
5108
|
+
StreamReader(const std::function<Size(Span<uint8_t>)> &func, const char *filename,
|
|
4956
5109
|
CompressionType compression_type = CompressionType::None)
|
|
4957
|
-
: StreamReader() { Open(
|
|
4958
|
-
StreamReader(int fd, const char *filename, unsigned int flags = 0,
|
|
4959
|
-
CompressionType compression_type = CompressionType::None)
|
|
4960
|
-
: StreamReader() { Open(fd, filename, flags, compression_type); }
|
|
4961
|
-
StreamReader(const char *filename, unsigned int flags = 0,
|
|
4962
|
-
CompressionType compression_type = CompressionType::None)
|
|
4963
|
-
: StreamReader() { Open(filename, flags, compression_type); }
|
|
4964
|
-
StreamReader(const std::function<Size(Span<uint8_t>)> &func, const char *filename, unsigned int flags = 0,
|
|
4965
|
-
CompressionType compression_type = CompressionType::None)
|
|
4966
|
-
: StreamReader() { Open(func, filename, flags, compression_type); }
|
|
5110
|
+
: StreamReader() { Open(func, filename, compression_type); }
|
|
4967
5111
|
~StreamReader() { Close(true); }
|
|
4968
5112
|
|
|
4969
5113
|
// Call before Open. Takes ownership and deletes the decoder at the end.
|
|
4970
5114
|
void SetDecoder(StreamDecoder *decoder);
|
|
4971
5115
|
|
|
4972
|
-
bool Open(Span<const uint8_t> buf, const char *filename,
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
OpenResult Open(const char *filename, unsigned int flags = 0,
|
|
4977
|
-
CompressionType compression_type = CompressionType::None);
|
|
4978
|
-
bool Open(const std::function<Size(Span<uint8_t>)> &func, const char *filename, unsigned int flags = 0,
|
|
5116
|
+
bool Open(Span<const uint8_t> buf, const char *filename, CompressionType compression_type = CompressionType::None);
|
|
5117
|
+
bool Open(int fd, const char *filename, CompressionType compression_type = CompressionType::None);
|
|
5118
|
+
OpenResult Open(const char *filename, CompressionType compression_type = CompressionType::None);
|
|
5119
|
+
bool Open(const std::function<Size(Span<uint8_t>)> &func, const char *filename,
|
|
4979
5120
|
CompressionType compression_type = CompressionType::None);
|
|
4980
5121
|
bool Close() { return Close(false); }
|
|
4981
5122
|
|
|
@@ -4995,7 +5136,11 @@ public:
|
|
|
4995
5136
|
// Thread safe methods
|
|
4996
5137
|
Size Read(Span<uint8_t> out_buf);
|
|
4997
5138
|
Size Read(Span<char> out_buf) { return Read(out_buf.As<uint8_t>()); }
|
|
4998
|
-
|
|
5139
|
+
|
|
5140
|
+
// Thread safe methods
|
|
5141
|
+
Size ReadFill(Span<uint8_t> out_buf);
|
|
5142
|
+
Size ReadFill(Span<char> out_buf) { return ReadFill(out_buf.As<uint8_t>()); }
|
|
5143
|
+
Size ReadFill(Size buf_len, void *out_buf) { return ReadFill(MakeSpan((uint8_t *)out_buf, buf_len)); }
|
|
4999
5144
|
|
|
5000
5145
|
Size ReadAll(Size max_len, HeapArray<uint8_t> *out_buf);
|
|
5001
5146
|
Size ReadAll(Size max_len, HeapArray<char> *out_buf)
|
|
@@ -5017,12 +5162,12 @@ private:
|
|
|
5017
5162
|
static inline Size ReadFile(const char *filename, Span<uint8_t> out_buf)
|
|
5018
5163
|
{
|
|
5019
5164
|
StreamReader st(filename);
|
|
5020
|
-
return st.
|
|
5165
|
+
return st.ReadFill(out_buf);
|
|
5021
5166
|
}
|
|
5022
5167
|
static inline Size ReadFile(const char *filename, Span<char> out_buf)
|
|
5023
5168
|
{
|
|
5024
5169
|
StreamReader st(filename);
|
|
5025
|
-
return st.
|
|
5170
|
+
return st.ReadFill(out_buf);
|
|
5026
5171
|
}
|
|
5027
5172
|
static inline Size ReadFile(const char *filename, Size max_len, HeapArray<uint8_t> *out_buf)
|
|
5028
5173
|
{
|
|
@@ -5424,10 +5569,11 @@ struct TranslationTable {
|
|
|
5424
5569
|
|
|
5425
5570
|
extern "C" const Span<const TranslationTable> TranslationTables;
|
|
5426
5571
|
|
|
5427
|
-
void InitLocales(Span<const TranslationTable> tables);
|
|
5572
|
+
void InitLocales(Span<const TranslationTable> tables, const char *default_lang);
|
|
5428
5573
|
|
|
5429
|
-
// Resets the
|
|
5574
|
+
// Resets the locale to the process default if lang is NULL or is unknown
|
|
5430
5575
|
void ChangeThreadLocale(const char *name);
|
|
5576
|
+
const char *GetThreadLocale();
|
|
5431
5577
|
|
|
5432
5578
|
// ------------------------------------------------------------------------
|
|
5433
5579
|
// Options
|
|
@@ -5626,10 +5772,23 @@ bool OptionToFlagI(Span<const OptionDesc> options, Span<const char> str, T *out_
|
|
|
5626
5772
|
// ------------------------------------------------------------------------
|
|
5627
5773
|
|
|
5628
5774
|
struct PromptChoice {
|
|
5629
|
-
char c;
|
|
5630
5775
|
const char *str;
|
|
5776
|
+
char c;
|
|
5777
|
+
};
|
|
5778
|
+
|
|
5779
|
+
enum class CompleteResult {
|
|
5780
|
+
Success,
|
|
5781
|
+
TooMany,
|
|
5782
|
+
Error
|
|
5631
5783
|
};
|
|
5632
5784
|
|
|
5785
|
+
struct CompleteChoice {
|
|
5786
|
+
const char *name;
|
|
5787
|
+
const char *value;
|
|
5788
|
+
};
|
|
5789
|
+
|
|
5790
|
+
typedef CompleteResult CompleteFunc(Span<const char> value, Allocator *alloc, HeapArray<CompleteChoice> *out_choices);
|
|
5791
|
+
|
|
5633
5792
|
class ConsolePrompter {
|
|
5634
5793
|
int prompt_columns = 0;
|
|
5635
5794
|
|
|
@@ -5651,6 +5810,7 @@ class ConsolePrompter {
|
|
|
5651
5810
|
public:
|
|
5652
5811
|
const char *prompt = ">>>";
|
|
5653
5812
|
const char *mask = nullptr;
|
|
5813
|
+
std::function<CompleteFunc> complete = {};
|
|
5654
5814
|
|
|
5655
5815
|
HeapArray<char> str;
|
|
5656
5816
|
|
|
@@ -5695,6 +5855,13 @@ static inline const char *Prompt(const char *prompt, Allocator *alloc)
|
|
|
5695
5855
|
Size PromptEnum(const char *prompt, Span<const PromptChoice> choices, Size value = 0);
|
|
5696
5856
|
Size PromptEnum(const char *prompt, Span<const char *const> strings, Size value = 0);
|
|
5697
5857
|
|
|
5858
|
+
// Returns -1 if cancelled, otherwise it's 1 for Yes and or 0 for No
|
|
5859
|
+
int PromptYN(const char *prompt);
|
|
5860
|
+
|
|
5861
|
+
const char *PromptPath(const char *prompt, const char *default_path, Span<const char> root_directory, Allocator *alloc);
|
|
5862
|
+
static inline const char *PromptPath(const char *prompt, Allocator *alloc)
|
|
5863
|
+
{ return PromptPath(prompt, nullptr, GetWorkingDirectory(), alloc); }
|
|
5864
|
+
|
|
5698
5865
|
// ------------------------------------------------------------------------
|
|
5699
5866
|
// Mime types
|
|
5700
5867
|
// ------------------------------------------------------------------------
|