diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-03-21 21:48:53 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-03-21 21:48:53 -0400 |
| commit | 5ee185a4896e43c67b6d299becfa616da78fb9f4 (patch) | |
| tree | 183ceef2fd21230c89334d7d039255d1c86c5dca /stdlib/structs.c | |
| parent | f4aaf7b73481248f6768302be688700a364a1af8 (diff) | |
Move stdlib into src/
Diffstat (limited to 'stdlib/structs.c')
| -rw-r--r-- | stdlib/structs.c | 237 |
1 files changed, 0 insertions, 237 deletions
diff --git a/stdlib/structs.c b/stdlib/structs.c deleted file mode 100644 index ca88262c..00000000 --- a/stdlib/structs.c +++ /dev/null @@ -1,237 +0,0 @@ -// Metamethods for structs - -#include <stdint.h> -#include <string.h> - -#include "arrays.h" -#include "bools.h" -#include "functiontype.h" -#include "metamethods.h" -#include "optionals.h" -#include "pointers.h" -#include "siphash.h" -#include "tables.h" -#include "text.h" -#include "util.h" - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstack-protector" -PUREFUNC public uint64_t Struct$hash(const void *obj, const TypeInfo_t *type) -{ - if (type->StructInfo.num_fields == 0) - return 0; - - if (type->StructInfo.num_fields == 1) - return generic_hash(obj, type->StructInfo.fields[0].type); - - uint64_t field_hashes[type->StructInfo.num_fields]; - ptrdiff_t byte_offset = 0; - ptrdiff_t bit_offset = 0; - for (int i = 0; i < type->StructInfo.num_fields; i++) { - NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { - bool b = ((*(char*)(obj + byte_offset)) >> bit_offset) & 0x1; - field_hashes[i] = (uint32_t)b; - bit_offset += 1; - if (bit_offset >= 8) { - byte_offset += 1; - bit_offset = 0; - } - } else { - if (bit_offset > 0) { - byte_offset += 1; - bit_offset = 0; - } - if (field.type->align && byte_offset % field.type->align > 0) - byte_offset += field.type->align - (byte_offset % field.type->align); - field_hashes[i] = generic_hash(obj + byte_offset, field.type); - byte_offset += field.type->size; - } - } - return siphash24((void*)field_hashes, sizeof(field_hashes)); -} -#pragma GCC diagnostic pop - -PUREFUNC public uint64_t PackedData$hash(const void *obj, const TypeInfo_t *type) -{ - if (type->StructInfo.num_fields == 0) - return 0; - - return siphash24(obj, (size_t)type->size); -} - -PUREFUNC public int32_t Struct$compare(const void *x, const void *y, const TypeInfo_t *type) -{ - if (x == y) - return 0; - - ptrdiff_t byte_offset = 0; - ptrdiff_t bit_offset = 0; - for (int i = 0; i < type->StructInfo.num_fields; i++) { - NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { - bool bx = ((*(char*)(x + byte_offset)) >> bit_offset) & 0x1; - bool by = ((*(char*)(y + byte_offset)) >> bit_offset) & 0x1; - if (bx != by) - return (int32_t)bx - (int32_t)by; - bit_offset += 1; - if (bit_offset >= 8) { - byte_offset += 1; - bit_offset = 0; - } - } else { - if (bit_offset > 0) { - byte_offset += 1; - bit_offset = 0; - } - if (field.type->align && byte_offset % field.type->align > 0) - byte_offset += field.type->align - (byte_offset % field.type->align); - int32_t cmp = generic_compare(x + byte_offset, y + byte_offset, field.type); - if (cmp != 0) - return cmp; - byte_offset += field.type->size; - } - } - return 0; -} - -PUREFUNC public bool Struct$equal(const void *x, const void *y, const TypeInfo_t *type) -{ - if (x == y) - return true; - - ptrdiff_t byte_offset = 0; - ptrdiff_t bit_offset = 0; - for (int i = 0; i < type->StructInfo.num_fields; i++) { - NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { - bool bx = ((*(char*)(x + byte_offset)) >> bit_offset) & 0x1; - bool by = ((*(char*)(y + byte_offset)) >> bit_offset) & 0x1; - if (bx != by) - return false; - bit_offset += 1; - if (bit_offset >= 8) { - byte_offset += 1; - bit_offset = 0; - } - } else { - if (bit_offset > 0) { - byte_offset += 1; - bit_offset = 0; - } - if (field.type->align && byte_offset % field.type->align > 0) - byte_offset += field.type->align - (byte_offset % field.type->align); - if (!generic_equal(x + byte_offset, y + byte_offset, field.type)) - return false; - byte_offset += field.type->size; - } - } - return true; -} - -PUREFUNC public bool PackedData$equal(const void *x, const void *y, const TypeInfo_t *type) -{ - if (x == y) return true; - return (memcmp(x, y, (size_t)type->size) == 0); -} - -PUREFUNC public Text_t Struct$as_text(const void *obj, bool colorize, const TypeInfo_t *type) -{ - if (!obj) return Text$from_str(type->StructInfo.name); - - if (type->StructInfo.is_secret || type->StructInfo.is_opaque) - return Text$format(colorize ? "\x1b[0;1m%s\x1b[m(...)" : "%s(...)", type->StructInfo.name); - - Text_t text = Text$format(colorize ? "\x1b[0;1m%s\x1b[m(" : "%s(", type->StructInfo.name); - ptrdiff_t byte_offset = 0; - ptrdiff_t bit_offset = 0; - for (int i = 0; i < type->StructInfo.num_fields; i++) { - NamedType_t field = type->StructInfo.fields[i]; - if (i > 0) - text = Text$concat(text, Text(", ")); - - if (type->StructInfo.num_fields > 1) - text = Text$concat(text, Text$from_str(field.name), Text("=")); - - if (field.type == &Bool$info) { - bool b = ((*(char*)(obj + byte_offset)) >> bit_offset) & 0x1; - text = Text$concat(text, Text$from_str(colorize ? (b ? "\x1b[35myes\x1b[m" : "\x1b[35mno\x1b[m") : (b ? "yes" : "no"))); - bit_offset += 1; - if (bit_offset >= 8) { - byte_offset += 1; - bit_offset = 0; - } - } else { - if (bit_offset > 0) { - byte_offset += 1; - bit_offset = 0; - } - if (field.type->align && byte_offset % field.type->align > 0) - byte_offset += field.type->align - (byte_offset % field.type->align); - text = Text$concat(text, generic_as_text(obj + byte_offset, colorize, field.type)); - byte_offset += field.type->size; - } - } - return Text$concat(text, Text(")")); -} - -PUREFUNC public bool Struct$is_none(const void *obj, const TypeInfo_t *type) -{ - return *(bool*)(obj + type->size); -} - -public void Struct$serialize(const void *obj, FILE *out, Table_t *pointers, const TypeInfo_t *type) -{ - ptrdiff_t byte_offset = 0; - ptrdiff_t bit_offset = 0; - for (int i = 0; i < type->StructInfo.num_fields; i++) { - NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { - bool b = ((*(char*)(obj + byte_offset)) >> bit_offset) & 0x1; - fputc((int)b, out); - bit_offset += 1; - if (bit_offset >= 8) { - byte_offset += 1; - bit_offset = 0; - } - } else { - if (bit_offset > 0) { - byte_offset += 1; - bit_offset = 0; - } - if (field.type->align && byte_offset % field.type->align > 0) - byte_offset += field.type->align - (byte_offset % field.type->align); - _serialize(obj + byte_offset, out, pointers, field.type); - byte_offset += field.type->size; - } - } -} - -public void Struct$deserialize(FILE *in, void *outval, Array_t *pointers, const TypeInfo_t *type) -{ - ptrdiff_t byte_offset = 0; - ptrdiff_t bit_offset = 0; - for (int i = 0; i < type->StructInfo.num_fields; i++) { - NamedType_t field = type->StructInfo.fields[i]; - if (field.type == &Bool$info) { - bool b = (bool)fgetc(in); - *(char*)(outval + byte_offset) |= (b << bit_offset); - bit_offset += 1; - if (bit_offset >= 8) { - byte_offset += 1; - bit_offset = 0; - } - } else { - if (bit_offset > 0) { - byte_offset += 1; - bit_offset = 0; - } - if (field.type->align && byte_offset % field.type->align > 0) - byte_offset += field.type->align - (byte_offset % field.type->align); - _deserialize(in, outval + byte_offset, pointers, field.type); - byte_offset += field.type->size; - } - } -} - -// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 |
