Changeset 29e7cc7 in mainline for uspace/lib
- Timestamp:
- 2025-04-18T15:14:10Z (9 months ago)
- Children:
- e77c3ed
- Parents:
- 800d188 (diff), 25fdb2d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/lib
- Files:
-
- 1 added
- 2 deleted
- 22 edited
- 1 moved
-
block/block.c (modified) (1 diff)
-
c/arch/arm32/src/atomic.c (modified) (2 diffs)
-
c/generic/async/ports.c (modified) (3 diffs)
-
c/generic/async/server.c (modified) (2 diffs)
-
c/generic/io/asprintf.c (modified) (2 diffs)
-
c/generic/io/kio.c (modified) (4 diffs)
-
c/generic/io/vprintf.c (modified) (2 diffs)
-
c/generic/io/vsnprintf.c (deleted)
-
c/include/io/kio.h (modified) (2 diffs)
-
c/include/stdio.h (modified) (1 diff)
-
c/include/types/adt/odict.h (deleted)
-
c/meson.build (modified) (4 diffs)
-
c/test/adt/odict.c (modified) (1 diff)
-
c/test/main.c (modified) (1 diff)
-
c/test/sprintf.c (modified) (4 diffs)
-
c/test/str.c (modified) (3 diffs)
-
c/test/uchar.c (added)
-
ext4/src/extent.c (modified) (1 diff)
-
ext4/src/ops.c (modified) (1 diff)
-
futil/include/futil.h (modified) (2 diffs)
-
futil/include/types/futil.h (moved) (moved from uspace/lib/c/include/wchar.h ) (2 diffs)
-
futil/src/futil.c (modified) (9 diffs)
-
nic/src/nic_addr_db.c (modified) (8 diffs)
-
nic/src/nic_wol_virtues.c (modified) (1 diff)
-
posix/src/stdio.c (modified) (2 diffs)
-
ui/src/msgdialog.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/block.c
r800d188 r29e7cc7 254 254 } 255 255 256 static bool cache_key_equal(const void *key, const ht_link_t *item)256 static bool cache_key_equal(const void *key, size_t hash, const ht_link_t *item) 257 257 { 258 258 const aoff64_t *lba = key; -
uspace/lib/c/arch/arm32/src/atomic.c
r800d188 r29e7cc7 38 38 volatile unsigned *ras_page; 39 39 40 bool __atomic_compare_exchange_4(volatile void *mem0, void *expected0, 41 unsigned desired, bool weak, int success, int failure) 40 unsigned long long __atomic_load_8(const volatile void *mem0, int model) 41 { 42 const volatile unsigned *mem = mem0; 43 44 (void) model; 45 46 union { 47 unsigned long long a; 48 unsigned b[2]; 49 } ret; 50 51 /* 52 * The following instructions between labels 1 and 2 constitute a 53 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 54 * the kernel will restart it. 55 */ 56 asm volatile ( 57 "1:\n" 58 " adr %[ret0], 1b\n" 59 " str %[ret0], %[rp0]\n" 60 " adr %[ret0], 2f\n" 61 " str %[ret0], %[rp1]\n" 62 63 " ldr %[ret0], %[addr0]\n" 64 " ldr %[ret1], %[addr1]\n" 65 "2:\n" 66 : [ret0] "=&r" (ret.b[0]), 67 [ret1] "=&r" (ret.b[1]), 68 [rp0] "=m" (ras_page[0]), 69 [rp1] "=m" (ras_page[1]) 70 : [addr0] "m" (mem[0]), 71 [addr1] "m" (mem[1]) 72 ); 73 74 ras_page[0] = 0; 75 ras_page[1] = 0xffffffff; 76 77 return ret.a; 78 } 79 80 void __atomic_store_8(volatile void *mem0, unsigned long long val, int model) 42 81 { 43 82 volatile unsigned *mem = mem0; 44 unsigned *expected = expected0; 83 84 (void) model; 85 86 union { 87 unsigned long long a; 88 unsigned b[2]; 89 } v; 90 91 v.a = val; 92 93 /* scratch register */ 94 unsigned tmp; 95 96 /* 97 * The following instructions between labels 1 and 2 constitute a 98 * Restartable Atomic Seqeunce. Should the sequence be non-atomic, 99 * the kernel will restart it. 100 */ 101 asm volatile ( 102 "1:\n" 103 " adr %[tmp], 1b\n" 104 " str %[tmp], %[rp0]\n" 105 " adr %[tmp], 2f\n" 106 " str %[tmp], %[rp1]\n" 107 108 " str %[val0], %[addr0]\n" 109 " str %[val1], %[addr1]\n" 110 "2:\n" 111 : [tmp] "=&r" (tmp), 112 [rp0] "=m" (ras_page[0]), 113 [rp1] "=m" (ras_page[1]), 114 [addr0] "=m" (mem[0]), 115 [addr1] "=m" (mem[1]) 116 : [val0] "r" (v.b[0]), 117 [val1] "r" (v.b[1]) 118 ); 119 120 ras_page[0] = 0; 121 ras_page[1] = 0xffffffff; 122 } 123 124 bool __atomic_compare_exchange_1(volatile void *mem0, void *expected0, 125 unsigned char desired, bool weak, int success, int failure) 126 { 127 volatile unsigned char *mem = mem0; 128 unsigned char *expected = expected0; 45 129 46 130 (void) success; … … 48 132 (void) weak; 49 133 134 unsigned char ov = *expected; 135 unsigned ret; 136 137 /* 138 * The following instructions between labels 1 and 2 constitute a 139 * Restartable Atomic Sequence. Should the sequence be non-atomic, 140 * the kernel will restart it. 141 */ 142 asm volatile ( 143 "1:\n" 144 " adr %[ret], 1b\n" 145 " str %[ret], %[rp0]\n" 146 " adr %[ret], 2f\n" 147 " str %[ret], %[rp1]\n" 148 149 " ldrb %[ret], %[addr]\n" 150 " cmp %[ret], %[ov]\n" 151 " streqb %[nv], %[addr]\n" 152 "2:\n" 153 : [ret] "=&r" (ret), 154 [rp0] "=m" (ras_page[0]), 155 [rp1] "=m" (ras_page[1]), 156 [addr] "+m" (*mem) 157 : [ov] "r" (ov), 158 [nv] "r" (desired) 159 ); 160 161 ras_page[0] = 0; 162 ras_page[1] = 0xffffffff; 163 164 if (ret == ov) 165 return true; 166 167 *expected = ret; 168 return false; 169 } 170 171 bool __atomic_compare_exchange_4(volatile void *mem0, void *expected0, 172 unsigned desired, bool weak, int success, int failure) 173 { 174 volatile unsigned *mem = mem0; 175 unsigned *expected = expected0; 176 177 (void) success; 178 (void) failure; 179 (void) weak; 180 50 181 unsigned ov = *expected; 51 182 unsigned ret; -
uspace/lib/c/generic/async/ports.c
r800d188 r29e7cc7 50 50 #include <as.h> 51 51 #include <abi/mm/as.h> 52 #include "../private/libc.h"53 52 #include "../private/fibril.h" 54 53 … … 115 114 } 116 115 117 static bool interface_key_equal(const void *key, const ht_link_t *item)116 static bool interface_key_equal(const void *key, size_t hash, const ht_link_t *item) 118 117 { 119 118 const iface_t *iface = key; … … 143 142 } 144 143 145 static bool port_key_equal(const void *key, const ht_link_t *item)144 static bool port_key_equal(const void *key, size_t hash, const ht_link_t *item) 146 145 { 147 146 const port_id_t *port_id = key; -
uspace/lib/c/generic/async/server.c
r800d188 r29e7cc7 242 242 } 243 243 244 static bool client_key_equal(const void *key, const ht_link_t *item)244 static bool client_key_equal(const void *key, size_t, const ht_link_t *item) 245 245 { 246 246 const task_id_t *in_task_id = key; … … 502 502 } 503 503 504 static bool notification_key_equal(const void *key, const ht_link_t *item)504 static bool notification_key_equal(const void *key, size_t hash, const ht_link_t *item) 505 505 { 506 506 const sysarg_t *id = key; -
uspace/lib/c/generic/io/asprintf.c
r800d188 r29e7cc7 40 40 #include <str.h> 41 41 #include <printf_core.h> 42 43 static int asprintf_str_write(const char *str, size_t count, void *unused)44 {45 return str_nlength(str, count);46 }47 48 static int asprintf_wstr_write(const char32_t *str, size_t count, void *unused)49 {50 return wstr_nlength(str, count);51 }52 53 int vprintf_length(const char *fmt, va_list args)54 {55 printf_spec_t ps = {56 asprintf_str_write,57 asprintf_wstr_write,58 NULL59 };60 61 return printf_core(fmt, &ps, args);62 }63 64 int printf_length(const char *fmt, ...)65 {66 va_list args;67 va_start(args, fmt);68 int ret = vprintf_length(fmt, args);69 va_end(args);70 71 return ret;72 }73 42 74 43 /** Allocate and print to string. … … 115 84 int ret = vasprintf(strp, fmt, args); 116 85 va_end(args); 117 118 86 return ret; 119 87 } -
uspace/lib/c/generic/io/kio.c
r800d188 r29e7cc7 34 34 */ 35 35 36 #include <abi/syscall.h> 36 37 #include <stddef.h> 37 38 #include <libc.h> … … 112 113 } 113 114 115 size_t kio_read(char *buf, size_t n, size_t at) 116 { 117 return __SYSCALL3(SYS_KIO_READ, (sysarg_t) buf, n, at); 118 } 119 114 120 /** Print formatted text to kio. 115 121 * … … 131 137 } 132 138 133 static int kio_vprintf_str_write(const char *str, size_t size, void *data)139 static errno_t kio_vprintf_str_write(const char *str, size_t size, void *data) 134 140 { 135 size_t wr; 136 137 wr = 0; 138 (void) kio_write(str, size, &wr); 139 return str_nlength(str, wr); 140 } 141 142 static int kio_vprintf_wstr_write(const char32_t *str, size_t size, void *data) 143 { 144 size_t offset = 0; 145 size_t chars = 0; 146 size_t wr; 147 148 while (offset < size) { 149 char buf[STR_BOUNDS(1)]; 150 size_t sz = 0; 151 152 if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK) 153 kio_write(buf, sz, &wr); 154 155 chars++; 156 offset += sizeof(char32_t); 157 } 158 159 return chars; 141 size_t wr = 0; 142 return kio_write(str, size, &wr); 160 143 } 161 144 … … 172 155 printf_spec_t ps = { 173 156 kio_vprintf_str_write, 174 kio_vprintf_wstr_write,175 157 NULL 176 158 }; -
uspace/lib/c/generic/io/vprintf.c
r800d188 r29e7cc7 42 42 static FIBRIL_MUTEX_INITIALIZE(printf_mutex); 43 43 44 static int vprintf_str_write(const char *str, size_t size, void *stream)44 static errno_t vprintf_str_write(const char *str, size_t size, void *stream) 45 45 { 46 size_t wr = fwrite(str, 1, size, (FILE *) stream); 47 return str_nlength(str, wr); 48 } 46 errno_t old_errno = errno; 49 47 50 static int vprintf_wstr_write(const char32_t *str, size_t size, void *stream) 51 { 52 size_t offset = 0; 53 size_t chars = 0; 48 errno = EOK; 49 size_t written = fwrite(str, 1, size, (FILE *) stream); 54 50 55 while (offset < size) { 56 if (fputuc(str[chars], (FILE *) stream) <= 0) 57 break; 51 if (errno == EOK && written != size) 52 errno = EIO; 58 53 59 chars++; 60 offset += sizeof(char32_t); 61 } 54 if (errno != EOK) 55 return errno; 62 56 63 return chars; 57 errno = old_errno; 58 return EOK; 64 59 } 65 60 … … 77 72 printf_spec_t ps = { 78 73 vprintf_str_write, 79 vprintf_wstr_write,80 74 stream 81 75 }; -
uspace/lib/c/include/io/kio.h
r800d188 r29e7cc7 36 36 #define _LIBC_IO_KIO_H_ 37 37 38 #include <stddef.h>39 #include <stdarg.h>40 #include <io/verify.h>41 38 #include <_bits/errno.h> 42 39 #include <_bits/size_t.h> 40 #include <io/verify.h> 41 #include <stdarg.h> 42 #include <stddef.h> 43 #include <uchar.h> 43 44 44 45 extern void __kio_init(void); … … 50 51 _HELENOS_PRINTF_ATTRIBUTE(1, 2); 51 52 extern int kio_vprintf(const char *, va_list); 53 54 extern size_t kio_read(char *buf, size_t n, size_t at); 52 55 53 56 /* -
uspace/lib/c/include/stdio.h
r800d188 r29e7cc7 209 209 }; 210 210 211 extern int vprintf_length(const char *, va_list);212 extern int printf_length(const char *, ...)213 _HELENOS_PRINTF_ATTRIBUTE(1, 2);214 211 extern FILE *fdopen(int, const char *); 215 212 extern int fileno(FILE *); -
uspace/lib/c/meson.build
r800d188 r29e7cc7 62 62 'common/adt/checksum.c', 63 63 'common/adt/circ_buf.c', 64 'common/adt/hash_table.c', 64 65 'common/adt/list.c', 65 'common/adt/hash_table.c',66 66 'common/adt/odict.c', 67 'common/gsort.c', 67 68 'common/printf/printf_core.c', 69 'common/stdc/bsearch.c', 70 'common/stdc/calloc.c', 68 71 'common/stdc/ctype.c', 69 72 'common/stdc/mem.c', 70 'common/stdc/bsearch.c',71 73 'common/stdc/qsort.c', 72 'common/stdc/calloc.c', 73 'common/gsort.c', 74 'common/stdc/snprintf.c', 75 'common/stdc/uchar.c', 76 'common/stdc/vsnprintf.c', 77 'common/stdc/wchar.c', 74 78 'common/str.c', 75 79 'common/str_error.c', 76 80 'common/strtol.c', 77 81 78 'generic/libc.c',79 82 'generic/adt/prodcons.c', 83 'generic/arg_parse.c', 80 84 'generic/as.c', 81 'generic/ddi.c', 82 'generic/perm.c', 85 'generic/assert.c', 86 'generic/async/client.c', 87 'generic/async/ports.c', 88 'generic/async/server.c', 83 89 'generic/capa.c', 84 90 'generic/config.c', 85 91 'generic/context.c', 86 92 'generic/dbgcon.c', 93 'generic/ddi.c', 87 94 'generic/device/clock_dev.c', 88 95 'generic/device/hw_res.c', … … 91 98 'generic/dirent.c', 92 99 'generic/dlfcn.c', 100 'generic/double_to_str.c', 93 101 'generic/elf/elf.c', 94 102 'generic/elf/elf_load.c', 95 103 'generic/elf/elf_mod.c', 104 'generic/errno.c', 96 105 'generic/event.c', 97 'generic/errno.c', 106 'generic/getopt.c', 107 'generic/ieee_double.c', 108 'generic/imath.c', 98 109 'generic/inttypes.c', 99 'generic/loc.c',100 'generic/string.c',101 'generic/l18n/langs.c',102 'generic/pcb.c',103 'generic/pio_trace.c',104 'generic/smc.c',105 'generic/task.c',106 'generic/imath.c',107 110 'generic/io/asprintf.c', 108 111 'generic/io/io.c', 109 'generic/io/printf.c', 112 'generic/io/kio.c', 113 'generic/io/klog.c', 110 114 'generic/io/log.c', 111 115 'generic/io/logctl.c', 112 'generic/io/kio.c', 113 'generic/io/klog.c', 114 'generic/io/snprintf.c', 116 'generic/io/printf.c', 117 'generic/io/table.c', 115 118 'generic/io/vprintf.c', 116 'generic/io/vsnprintf.c', 117 'generic/io/table.c', 119 'generic/ipc.c', 118 120 'generic/irq.c', 119 'generic/ieee_double.c', 121 'generic/l18n/langs.c', 122 'generic/libc.c', 123 'generic/loader.c', 124 'generic/loc.c', 125 'generic/malloc.c', 126 'generic/ns.c', 127 'generic/pcb.c', 128 'generic/perm.c', 129 'generic/pio_trace.c', 120 130 'generic/power_of_ten.c', 121 'generic/double_to_str.c',122 'generic/malloc.c',123 131 'generic/rndgen.c', 132 'generic/setjmp.c', 124 133 'generic/shutdown.c', 134 'generic/smc.c', 135 'generic/stack.c', 136 'generic/stacktrace.c', 137 'generic/stats.c', 138 'generic/stdio.c', 125 139 'generic/stdio/scanf.c', 126 140 'generic/stdio/sprintf.c', … … 128 142 'generic/stdio/sstream.c', 129 143 'generic/stdio/vsprintf.c', 144 'generic/stdlib.c', 145 'generic/string.c', 146 'generic/sysinfo.c', 147 'generic/task.c', 130 148 'generic/thread/fibril.c', 131 149 'generic/thread/fibril_synch.c', 150 'generic/thread/futex.c', 151 'generic/thread/mpsc.c', 132 152 'generic/thread/thread.c', 133 153 'generic/thread/tls.c', 134 'generic/thread/futex.c',135 'generic/thread/mpsc.c',136 'generic/sysinfo.c',137 'generic/ipc.c',138 'generic/ns.c',139 'generic/async/client.c',140 'generic/async/server.c',141 'generic/async/ports.c',142 'generic/loader.c',143 'generic/getopt.c',144 154 'generic/time.c', 145 155 'generic/tmpfile.c', 146 'generic/stdio.c', 147 'generic/stdlib.c', 156 'generic/ubsan.c', 148 157 'generic/udebug.c', 158 'generic/uuid.c', 149 159 'generic/vfs/canonify.c', 150 160 'generic/vfs/inbox.c', 151 161 'generic/vfs/mtab.c', 152 162 'generic/vfs/vfs.c', 153 'generic/setjmp.c',154 'generic/stack.c',155 'generic/stacktrace.c',156 'generic/arg_parse.c',157 'generic/stats.c',158 'generic/assert.c',159 'generic/ubsan.c',160 'generic/uuid.c',161 163 ) 162 164 163 165 if CONFIG_RTLD 164 166 src += files( 165 'generic/rtld/rtld.c',166 167 'generic/rtld/dynamic.c', 167 168 'generic/rtld/module.c', 169 'generic/rtld/rtld.c', 168 170 'generic/rtld/symbol.c', 169 171 ) … … 190 192 'test/qsort.c', 191 193 'test/sprintf.c', 194 'test/stdio.c', 192 195 'test/stdio/scanf.c', 193 'test/stdio.c',194 196 'test/stdlib.c', 195 197 'test/str.c', 196 198 'test/string.c', 197 199 'test/strtol.c', 200 'test/uchar.c', 198 201 'test/uuid.c', 199 202 ) -
uspace/lib/c/test/adt/odict.c
r800d188 r29e7cc7 233 233 234 234 e->key = v; 235 odict_insert(&e->odict, &odict, &ep->odict);235 odict_insert(&e->odict, &odict, ep ? &ep->odict : NULL); 236 236 PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict)); 237 237 v = seq_next(v); -
uspace/lib/c/test/main.c
r800d188 r29e7cc7 57 57 PCUT_IMPORT(strtol); 58 58 PCUT_IMPORT(table); 59 PCUT_IMPORT(uchar); 59 60 PCUT_IMPORT(uuid); 60 61 -
uspace/lib/c/test/sprintf.c
r800d188 r29e7cc7 1 1 /* 2 2 * Copyright (c) 2014 Vojtech Horky 3 * Copyright (c) 2025 Jiří Zárevúcky 3 4 * All rights reserved. 4 5 * … … 31 32 #include <pcut/pcut.h> 32 33 34 #pragma GCC diagnostic ignored "-Wformat" 35 33 36 #define BUFFER_SIZE 8192 34 37 #define TEQ(expected, actual) PCUT_ASSERT_STR_EQUALS(expected, actual) … … 36 39 37 40 #define SPRINTF_TEST(test_name, expected_string, actual_format, ...) \ 38 PCUT_TEST( test_name) { \41 PCUT_TEST(printf_##test_name) { \ 39 42 snprintf(buffer, BUFFER_SIZE, actual_format, ##__VA_ARGS__); \ 40 43 PCUT_ASSERT_STR_EQUALS(expected_string, buffer); \ … … 79 82 (long long) -5); 80 83 81 SPRINTF_TEST(int_as_hex, "[0x11] [0x012] [0x013] [0x00014] [0x00015]", 82 "[%#x] [%#5.3x] [%#-5.3x] [%#3.5x] [%#-3.5x]", 83 17, 18, 19, 20, 21); 84 SPRINTF_TEST(int_as_hex, "[1a] [ 02b] [03c ] [ 04d] [05e ] [0006f] [00080]", 85 "[%x] [%5.3x] [%-5.3x] [%7.3x] [%-7.3x] [%3.5x] [%-3.5x]", 86 26, 43, 60, 77, 94, 111, 128); 87 88 SPRINTF_TEST(int_as_hex_alt, "[0x1a] [0x02b] [0x03c] [ 0x04d] [0x05e ] [0x0006f] [0x00080]", 89 "[%#x] [%#5.3x] [%#-5.3x] [%#7.3x] [%#-7.3x] [%#3.5x] [%#-3.5x]", 90 26, 43, 60, 77, 94, 111, 128); 91 92 SPRINTF_TEST(int_as_hex_uc, "[1A] [ 02B] [03C ] [ 04D] [05E ] [0006F] [00080]", 93 "[%X] [%5.3X] [%-5.3X] [%7.3X] [%-7.3X] [%3.5X] [%-3.5X]", 94 26, 43, 60, 77, 94, 111, 128); 95 96 SPRINTF_TEST(int_as_hex_alt_uc, "[0X1A] [0X02B] [0X03C] [ 0X04D] [0X05E ] [0X0006F] [0X00080]", 97 "[%#X] [%#5.3X] [%#-5.3X] [%#7.3X] [%#-7.3X] [%#3.5X] [%#-3.5X]", 98 26, 43, 60, 77, 94, 111, 128); 99 100 SPRINTF_TEST(max_negative, "-9223372036854775808", "%" PRId64, INT64_MIN); 101 102 SPRINTF_TEST(sign1, "[12] [ 12] [+12] [+12] [+12] [+12]", "[%d] [% d] [%+d] [% +d] [%+ d] [%++ ++ + ++++d]", 12, 12, 12, 12, 12, 12); 103 SPRINTF_TEST(sign2, "[-12] [-12] [-12] [-12] [-12] [-12]", "[%d] [% d] [%+d] [% +d] [%+ d] [%++ ++ + ++++d]", -12, -12, -12, -12, -12, -12); 104 105 /* When zero padding and precision and/or left justification are both specified, zero padding is ignored. */ 106 SPRINTF_TEST(zero_left_padding, "[ 0012] [0034 ] [56 ]", "[%08.4d] [%-08.4d] [%-08d]", 12, 34, 56); 107 108 /* Zero padding comes after the sign, but space padding doesn't. */ 109 SPRINTF_TEST(sign_padding, "[00012] [ 12] [ 0012] [ 12] [+0012] [ +12]", "[%05d] [%5d] [%0 5d] [% 5d] [%0+5d] [%+5d]", 12, 12, 12, 12, 12, 12); 110 SPRINTF_TEST(sign_padding2, "[-0012] [ -12] [-0012] [ -12] [-0012] [ -12]", "[%05d] [%5d] [%0 5d] [% 5d] [%0+5d] [%+5d]", -12, -12, -12, -12, -12, -12); 111 112 SPRINTF_TEST(all_zero, "[00000] [0] [0] [0] [0] [0] [0] [0] [0]", "[%05d] [%d] [%x] [%#x] [%o] [%#o] [%b] [%#b] [%u]", 0, 0, 0, 0, 0, 0, 0, 0, 0); 84 113 85 114 PCUT_EXPORT(sprintf); -
uspace/lib/c/test/str.c
r800d188 r29e7cc7 27 27 */ 28 28 29 #include "pcut/asserts.h" 30 #include <assert.h> 31 #include <stdint.h> 29 32 #include <stdio.h> 30 33 #include <str.h> … … 47 50 } 48 51 52 /* Helper to display string contents for debugging */ 53 static void print_string_hex(char *out, const char *s, size_t len) 54 { 55 *out++ = '"'; 56 for (size_t i = 0; i < len && s[i]; i++) { 57 if (s[i] >= 32 && s[i] <= 126) 58 *out++ = s[i]; 59 else 60 out += snprintf(out, 5, "\\x%02x", (uint8_t) s[i]); 61 } 62 *out++ = '"'; 63 *out++ = 0; 64 } 65 49 66 PCUT_TEST(rtrim) 50 67 { … … 115 132 } 116 133 134 PCUT_TEST(str_non_shortest) 135 { 136 /* Overlong zero. */ 137 const char overlong1[] = "\xC0\x80"; 138 const char overlong2[] = "\xE0\x80\x80"; 139 const char overlong3[] = "\xF0\x80\x80\x80"; 140 141 const char overlong4[] = "\xC1\xBF"; 142 const char overlong5[] = "\xE0\x9F\xBF"; 143 const char overlong6[] = "\xF0\x8F\xBF\xBF"; 144 145 size_t offset = 0; 146 PCUT_ASSERT_INT_EQUALS(U_SPECIAL, str_decode(overlong1, &offset, sizeof(overlong1))); 147 offset = 0; 148 PCUT_ASSERT_INT_EQUALS(U_SPECIAL, str_decode(overlong2, &offset, sizeof(overlong2))); 149 offset = 0; 150 PCUT_ASSERT_INT_EQUALS(U_SPECIAL, str_decode(overlong3, &offset, sizeof(overlong3))); 151 offset = 0; 152 PCUT_ASSERT_INT_EQUALS(U_SPECIAL, str_decode(overlong4, &offset, sizeof(overlong4))); 153 offset = 0; 154 PCUT_ASSERT_INT_EQUALS(U_SPECIAL, str_decode(overlong5, &offset, sizeof(overlong5))); 155 offset = 0; 156 PCUT_ASSERT_INT_EQUALS(U_SPECIAL, str_decode(overlong6, &offset, sizeof(overlong6))); 157 } 158 159 struct sanitize_test { 160 const char *input; 161 const char *output; 162 }; 163 164 static const struct sanitize_test sanitize_tests[] = { 165 // Empty string 166 { "", "" }, 167 // ASCII only 168 { "Hello, world!", "Hello, world!" }, 169 // Valid multi-byte sequences 170 { "Aπ你🐱", "Aπ你🐱" }, 171 // U+D7FF is last valid before surrogates 172 { "A\xED\x9F\xBFZ", "A\xED\x9F\xBFZ" }, 173 // 0x10FFFF is the highest legal code point 174 { "A\xF4\x8F\xBF\xBFZ", "A\xF4\x8F\xBF\xBFZ" }, 175 176 // Missing continuation byte 177 { "A\xC2Z", "A?Z" }, 178 // Truncated multi-byte at buffer end 179 { "A\xE2\x82", "A??" }, 180 // Continuation byte without leading byte (0x80-0xBF are never valid first bytes) 181 { "A\x80Y\xBFZ", "A?Y?Z" }, 182 183 // 'A' (U+0041) normally encoded as 0x41 184 // Overlong 2-byte encoding: 0xC1 0x81 185 { "\xC1\x81X", "??X" }, 186 187 // ¢ (U+00A2) normally encoded as 0xC2 0xA2 188 // Overlong 3-byte encoding: 0xE0 0x82 0xA2 189 { "\xE0\x82\xA2X", "???X" }, 190 191 // ¢ (U+00A2) normally encoded as 0xC2 0xA2 192 // Overlong 4-byte encoding: 0xF0 0x80 0x82 0xA2 193 { "\xF0\x80\x82\xA2X", "????X" }, 194 195 // € (U+20AC) normally encoded as 0xE2 0x82 0xAC 196 // Overlong 4-byte encoding: 0xF0 0x82 0x82 0xAC 197 { "\xF0\x82\x82\xACX", "????X" }, 198 199 // Using 0xC0 0x80 as overlong encoding for NUL (which should be just 0x00) 200 { "\xC0\x80X", "??X" }, 201 202 // 0xED 0xA0 0x80 encodes a surrogate half (U+D800), not allowed in UTF-8 203 { "A\xED\xA0\x80Z", "A???Z" }, 204 205 // 0x110000 is not a legal code point 206 { "A\xF4\x90\x80\x80Z", "A????Z" }, 207 208 // Mix of valid and invalid sequences 209 { "A\xC2\xA9\xE2\x28\xA1\xF0\x9F\x98\x81\x80Z", "A©?(?😁?Z" }, 210 }; 211 212 static size_t count_diff(const char *a, const char *b, size_t n) 213 { 214 size_t count = 0; 215 216 for (size_t i = 0; i < n; i++) { 217 if (a[i] != b[i]) 218 count++; 219 } 220 221 return count; 222 } 223 224 PCUT_TEST(str_sanitize) 225 { 226 char replacement = '?'; 227 char buffer2[255]; 228 229 for (size_t i = 0; i < sizeof(sanitize_tests) / sizeof(sanitize_tests[0]); i++) { 230 const char *in = sanitize_tests[i].input; 231 const char *out = sanitize_tests[i].output; 232 size_t n = str_size(in) + 1; 233 assert(str_size(out) + 1 == n); 234 235 memcpy(buffer, in, n); 236 size_t replaced = str_sanitize(buffer, n, replacement); 237 if (memcmp(buffer, out, n) != 0) { 238 print_string_hex(buffer2, buffer, n); 239 print_string_hex(buffer, out, n); 240 PCUT_ASSERTION_FAILED("Expected %s, got %s", buffer, buffer2); 241 } 242 243 size_t expect_replaced = count_diff(buffer, in, n); 244 PCUT_ASSERT_INT_EQUALS(expect_replaced, replaced); 245 } 246 247 // Test with n smaller than string length - truncated valid encoding for € 248 const char *in = "ABC€"; 249 const char *out = "ABC??\xAC"; 250 size_t n = str_size(in) + 1; 251 memcpy(buffer, in, n); 252 size_t replaced = str_sanitize(buffer, 5, replacement); 253 if (memcmp(buffer, out, n) != 0) { 254 print_string_hex(buffer2, buffer, n); 255 print_string_hex(buffer, out, n); 256 PCUT_ASSERTION_FAILED("Expected %s, got %s", buffer, buffer2); 257 } 258 259 PCUT_ASSERT_INT_EQUALS(2, replaced); 260 } 261 117 262 PCUT_EXPORT(str); -
uspace/lib/ext4/src/extent.c
r800d188 r29e7cc7 888 888 ext4_extent_path_t *old_root = path + 1; 889 889 890 size_t nbytes = sizeof(ext4_extent_path_t) * (path->depth + 1); 891 memmove(old_root, new_root, nbytes); 890 for (int i = path->depth; i >= 0; i--) 891 path[i + 1] = path[i]; 892 892 893 memset(new_root, 0, sizeof(ext4_extent_path_t)); 893 894 -
uspace/lib/ext4/src/ops.c
r800d188 r29e7cc7 113 113 } 114 114 115 static bool open_nodes_key_equal(const void *key_arg, const ht_link_t *item)115 static bool open_nodes_key_equal(const void *key_arg, size_t hash, const ht_link_t *item) 116 116 { 117 117 const node_key_t *key = key_arg; -
uspace/lib/futil/include/futil.h
r800d188 r29e7cc7 1 1 /* 2 * Copyright (c) 202 4Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 38 38 #define FUTIL_H 39 39 40 #include <errno.h> 40 41 #include <stddef.h> 42 #include "types/futil.h" 41 43 42 extern errno_t futil_copy_file(const char *, const char *); 43 extern errno_t futil_rcopy_contents(const char *, const char *); 44 extern errno_t futil_get_file(const char *, void **, size_t *); 44 extern errno_t futil_create(futil_cb_t *, void *, futil_t **); 45 extern void futil_destroy(futil_t *); 46 extern errno_t futil_copy_file(futil_t *, const char *, const char *); 47 extern errno_t futil_rcopy_contents(futil_t *, const char *, const char *); 48 extern errno_t futil_get_file(futil_t *, const char *, void **, size_t *); 45 49 46 50 #endif -
uspace/lib/futil/include/types/futil.h
r800d188 r29e7cc7 1 1 /* 2 * Copyright (c) 20 17 CZ.NIC, z.s.p.o.2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /* 30 * Authors: 31 * Jiří Zárevúcky (jzr) <zarevucky.jiri@gmail.com> 29 /** @addtogroup futil 30 * @{ 31 */ 32 /** 33 * @file 34 * @brief 32 35 */ 33 36 34 /** @addtogroup libc 35 * @{ 36 */ 37 /** @file 38 */ 37 #ifndef TYPES_FUTIL_H 38 #define TYPES_FUTIL_H 39 39 40 #ifndef _LIBC_WCHAR_H_ 41 #define _LIBC_WCHAR_H_ 40 /** File utility callbacks */ 41 typedef struct { 42 /** Copying file */ 43 void (*copy_file)(void *, const char *, const char *); 44 /** Creating directory */ 45 void (*create_dir)(void *, const char *); 46 } futil_cb_t; 42 47 43 #include <_bits/size_t.h> 44 #include <_bits/wchar_t.h> 45 #include <_bits/wchar_limits.h> 46 #include <_bits/wint_t.h> 47 #include <_bits/NULL.h> 48 #include <_bits/WEOF.h> 48 typedef struct { 49 /** Callback functions */ 50 futil_cb_t *cb; 51 /** Argument to callback functions */ 52 void *cb_arg; 53 } futil_t; 49 54 50 55 #endif -
uspace/lib/futil/src/futil.c
r800d188 r29e7cc7 1 1 /* 2 * Copyright (c) 202 4Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 47 47 static char buf[BUF_SIZE]; 48 48 49 /** Create file utility instance. 50 * 51 * @param cb Callback functions 52 * @param arg Argument to callback functions 53 * @param rfutil Place to store pointer to new file utility instance 54 * @return EOK on succcess, ENOMEM if out of memory. 55 */ 56 errno_t futil_create(futil_cb_t *cb, void *arg, futil_t **rfutil) 57 { 58 futil_t *futil; 59 60 futil = calloc(1, sizeof(futil_t)); 61 if (futil == NULL) 62 return ENOMEM; 63 64 futil->cb = cb; 65 futil->cb_arg = arg; 66 *rfutil = futil; 67 return EOK; 68 } 69 70 /** Destroy file utility instance. 71 * 72 * @param futil File utility instance 73 */ 74 void futil_destroy(futil_t *futil) 75 { 76 free(futil); 77 } 78 49 79 /** Copy file. 50 80 * 81 * @param futil File utility instance 51 82 * @param srcp Source path 52 83 * @param dstp Destination path … … 54 85 * @return EOK on success, EIO on I/O error 55 86 */ 56 errno_t futil_copy_file( const char *srcp, const char *destp)87 errno_t futil_copy_file(futil_t *futil, const char *srcp, const char *destp) 57 88 { 58 89 int sf, df; … … 61 92 aoff64_t posr = 0, posw = 0; 62 93 63 printf("Copy '%s' to '%s'.\n", srcp, destp); 94 if (futil->cb != NULL && futil->cb->copy_file != NULL) 95 futil->cb->copy_file(futil->cb_arg, srcp, destp); 64 96 65 97 rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf); … … 99 131 /** Copy contents of srcdir (recursively) into destdir. 100 132 * 133 * @param futil File utility instance 101 134 * @param srcdir Source directory 102 135 * @param destdir Destination directory … … 104 137 * @return EOK on success, ENOMEM if out of memory, EIO on I/O error 105 138 */ 106 errno_t futil_rcopy_contents(const char *srcdir, const char *destdir) 139 errno_t futil_rcopy_contents(futil_t *futil, const char *srcdir, 140 const char *destdir) 107 141 { 108 142 DIR *dir; … … 128 162 129 163 if (s.is_file) { 130 rc = futil_copy_file( srcp, destp);164 rc = futil_copy_file(futil, srcp, destp); 131 165 if (rc != EOK) 132 166 return EIO; 133 167 } else if (s.is_directory) { 134 printf("Create directory '%s'\n", destp); 168 if (futil->cb != NULL && futil->cb->create_dir != NULL) 169 futil->cb->create_dir(futil->cb_arg, destp); 135 170 rc = vfs_link_path(destp, KIND_DIRECTORY, NULL); 136 171 if (rc != EOK) 137 172 return EIO; 138 rc = futil_rcopy_contents( srcp, destp);173 rc = futil_rcopy_contents(futil, srcp, destp); 139 174 if (rc != EOK) 140 175 return EIO; … … 151 186 /** Return file contents as a heap-allocated block of bytes. 152 187 * 188 * @param futil File utility instance 153 189 * @param srcp File path 154 190 * @param rdata Place to store pointer to data … … 158 194 * I/O error, ENOMEM if out of memory 159 195 */ 160 errno_t futil_get_file(const char *srcp, void **rdata, size_t *rsize) 196 errno_t futil_get_file(futil_t *futil, const char *srcp, void **rdata, 197 size_t *rsize) 161 198 { 162 199 int sf; -
uspace/lib/nic/src/nic_addr_db.c
r800d188 r29e7cc7 52 52 typedef struct nic_addr_entry { 53 53 ht_link_t link; 54 size_t hash; 54 55 uint8_t len; 55 uint8_t addr[ 1];56 uint8_t addr[]; 56 57 } nic_addr_entry_t; 57 58 … … 60 61 */ 61 62 typedef struct { 63 size_t hash; 62 64 size_t len; 63 65 const uint8_t *addr; 64 66 } addr_key_t; 65 67 66 static bool nic_addr_key_equal(const void *key_arg, const ht_link_t *item)68 static bool nic_addr_key_equal(const void *key_arg, size_t hash, const ht_link_t *item) 67 69 { 68 70 const addr_key_t *key = key_arg; 69 71 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 70 71 return memcmp(entry->addr, key->addr, entry->len) == 0; 72 return entry->hash == hash && memcmp(entry->addr, key->addr, entry->len) == 0; 72 73 } 73 74 … … 86 87 { 87 88 const addr_key_t *key = k; 88 return addr_hash(key->len, key->addr);89 return key->hash ? key->hash : addr_hash(key->len, key->addr); 89 90 } 90 91 … … 92 93 { 93 94 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 94 return addr_hash(entry->len, entry->addr);95 return entry->hash; 95 96 } 96 97 … … 98 99 { 99 100 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 100 101 101 free(entry); 102 102 } … … 173 173 addr_key_t key = { 174 174 .len = db->addr_len, 175 .addr = addr 175 .addr = addr, 176 .hash = addr_hash(db->addr_len, addr), 176 177 }; 177 178 … … 179 180 return EEXIST; 180 181 181 nic_addr_entry_t *entry = malloc( sizeof(nic_addr_entry_t) + db->addr_len - 1);182 nic_addr_entry_t *entry = malloc(offsetof(nic_addr_entry_t, addr) + db->addr_len); 182 183 if (entry == NULL) 183 184 return ENOMEM; … … 185 186 entry->len = (uint8_t) db->addr_len; 186 187 memcpy(entry->addr, addr, db->addr_len); 188 entry->hash = key.hash; 187 189 188 190 hash_table_insert(&db->set, &entry->link); -
uspace/lib/nic/src/nic_wol_virtues.c
r800d188 r29e7cc7 57 57 } 58 58 59 static bool nic_wv_key_equal(const void *key, const ht_link_t *item)59 static bool nic_wv_key_equal(const void *key, size_t hash, const ht_link_t *item) 60 60 { 61 61 const nic_wv_id_t *k = key; -
uspace/lib/posix/src/stdio.c
r800d188 r29e7cc7 232 232 * @return The number of written characters. 233 233 */ 234 static int _dprintf_str_write(const char *str, size_t size, void *fd)234 static errno_t _dprintf_str_write(const char *str, size_t size, void *fd) 235 235 { 236 236 const int fildes = *(int *) fd; 237 237 size_t wr; 238 if (failed(vfs_write(fildes, &posix_pos[fildes], str, size, &wr))) 239 return -1; 240 return str_nlength(str, wr); 241 } 242 243 /** 244 * Write wide string to the opened file. 245 * 246 * @param str String to be written. 247 * @param size Size of the string (in bytes). 248 * @param fd File descriptor of the opened file. 249 * @return The number of written characters. 250 */ 251 static int _dprintf_wstr_write(const char32_t *str, size_t size, void *fd) 252 { 253 size_t offset = 0; 254 size_t chars = 0; 255 size_t sz; 256 char buf[4]; 257 258 while (offset < size) { 259 sz = 0; 260 if (chr_encode(str[chars], buf, &sz, sizeof(buf)) != EOK) { 261 break; 262 } 263 264 const int fildes = *(int *) fd; 265 size_t nwr; 266 if (vfs_write(fildes, &posix_pos[fildes], buf, sz, &nwr) != EOK) 267 break; 268 269 chars++; 270 offset += sizeof(char32_t); 271 } 272 273 return chars; 238 return vfs_write(fildes, &posix_pos[fildes], str, size, &wr); 274 239 } 275 240 … … 285 250 { 286 251 printf_spec_t spec = { 287 .str_write = _dprintf_str_write, 288 .wstr_write = _dprintf_wstr_write, 252 .write = _dprintf_str_write, 289 253 .data = &fildes 290 254 }; -
uspace/lib/ui/src/msgdialog.c
r800d188 r29e7cc7 1 1 /* 2 * Copyright (c) 202 4Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 125 125 wparams.rect.p0.x = 0; 126 126 wparams.rect.p0.y = 0; 127 wparams.rect.p1.x = 4 00;127 wparams.rect.p1.x = 440; 128 128 wparams.rect.p1.y = 110; 129 129 } … … 154 154 rect.p0.x = 10; 155 155 rect.p0.y = 35; 156 rect.p1.x = 390;156 rect.p1.x = 430; 157 157 rect.p1.y = 50; 158 158 }
Note:
See TracChangeset
for help on using the changeset viewer.
