#include "muscles.h"#include "structs.h"#include "format.h" #include <charconv> char *format_field_name(Arena& arena, String_Vector& in_vec, Field& field) { char *fname = in_vec.at(field.field_name_idx); if (!fname) fname = (char*)"???"; if (field.paste_field < 0) { field.parent_tag = nullptr; return fname; } Field *current = &field.paste_st->fields.data[field.paste_field]; int len = strlen(fname); int ptag_len = 0; if (current->parent_tag) { ptag_len = strlen(current->parent_tag); len += ptag_len + 1; } int array_idx = -1; if (current->array_len > 1) { len += 12; array_idx = field.paste_array_idx; } char *pname = in_vec.at(current->field_name_idx); if (!pname) pname = (char*)"???"; int pn_len = strlen(pname); len += pn_len + 1; char *name = (char*)arena.allocate(len + 1); char *p = name; if (ptag_len) { strcpy(p, current->parent_tag); p += ptag_len; *p++ = '.'; } strcpy(p, pname); p += pn_len; if (array_idx >= 0) p += snprintf(p, 12, "[%d]", array_idx); field.parent_tag = arena.alloc_string(name); *p++ = '.'; strcpy(p, fname); return name;} char *format_type_name(Arena& arena, String_Vector& in_vec, Field& field) { char *type_name = in_vec.at(field.type_name_idx); if (!type_name) type_name = (char*)"???"; int name_len = strlen(type_name); int extra_len = field.pointer_levels + 12; char *name = (char*)arena.allocate(name_len + extra_len); char *p = name; for (int j = 0; j < field.pointer_levels; j++) *p++ = '*'; strcpy(p, type_name); if (field.array_len > 0) { p += name_len; snprintf(p, extra_len - 1, "[%d]", field.array_len); } return name;} void format_field_value(Field& field, Value_Format& format, Span& span, char*& cell, int cell_len) { if (field.array_len > 0 || field.flags & FLAG_COMPOSITE || field.bit_size > 64 || field.bit_size <= 0) return; int offset = (field.bit_offset + 7) / 8; if (offset >= span.retrieved) { strcpy(cell, "???"); return; } memset(cell, 0, cell_len); if (field.array_len == 0 && field.bit_size <= 64) { u64 n = 0; bool byte_aligned = (field.bit_offset % 8 == 0) && (field.bit_size % 8 == 0); if (byte_aligned) { int bytes = field.bit_size / 8; if (field.flags & FLAG_BIG_ENDIAN) { for (int i = 0; i < bytes; i++) n = (n << 8) | span.data[offset + i]; } else memcpy(&n, &span.data[offset], bytes); } else { // Endian-ness is ignored when reading bit fields (ie. bit fields are big-endian only) int off = field.bit_offset; int out_pos = field.bit_size - 1; for (int j = 0; j < field.bit_size; j++, off++, out_pos--) { u8 byte = span.data[off / 8]; int bit = 7 - (off % 8); n |= (u64)((byte >> bit) & 1) << out_pos; } } if (field.flags & FLAG_FLOAT) { if (field.bit_size == 32) std::to_chars(cell, cell + cell_len, *(float*)&n); else if (field.bit_size == 64) std::to_chars(cell, cell + cell_len, *(double*)&n); } else { bool negative = (field.flags & FLAG_SIGNED) && (n >= 1LL << (u64)(field.bit_size - 1LL)); const char *prefix = "0x"; int pref_len = 2; if (negative) { n = -n; n &= (1LL << (u64)field.bit_size) - 1LL; prefix = "-0x"; pref_len = 3; } strcpy(cell, prefix); int digits = count_hex_digits(n); write_hex(&cell[pref_len], n, digits); } }}