util.c (3811B)
1 /* See LICENSE for copyright details */ 2 static b32 3 equal_iv2(iv2 a, iv2 b) 4 { 5 b32 result = a.x == b.x && a.y == b.y; 6 return result; 7 } 8 9 static b32 10 equal_uv2(uv2 a, uv2 b) 11 { 12 b32 result = a.x == b.x && a.y == b.y; 13 return result; 14 } 15 16 static b32 17 is_valid_range(Range r) 18 { 19 b32 result = !equal_iv2(r.end, INVALID_RANGE_END); 20 return result; 21 } 22 23 static Range 24 normalize_range(Range r) 25 { 26 Range result; 27 if (r.start.y < r.end.y) { 28 result = r; 29 } else if (r.end.y < r.start.y) { 30 result = (Range){.start = r.end, .end = r.start}; 31 } else { 32 result.start.y = result.end.y = r.start.y; 33 result.start.x = MIN(r.start.x, r.end.x); 34 result.end.x = MAX(r.start.x, r.end.x); 35 } 36 return result; 37 } 38 39 static void 40 mem_copy(s8 src, s8 dest) 41 { 42 ASSERT(src.len > 0 && dest.len > 0); 43 ASSERT(dest.len >= src.len); 44 for (size i = 0; i < src.len; i++) 45 dest.data[i] = src.data[i]; 46 } 47 48 static void * 49 mem_clear(void *p_, u8 c, size len) 50 { 51 u8 *p = p_; 52 while (len) p[--len] = c; 53 return p; 54 } 55 56 #define alloc(a, t, n) (t *)alloc_(a, sizeof(t), _Alignof(t), n) 57 __attribute((malloc, alloc_size(4, 2), alloc_align(3))) 58 static void * 59 alloc_(Arena *a, size len, size align, size count) 60 { 61 size padding = -(uintptr_t)a->beg & (align - 1); 62 size available = a->end - a->beg - padding; 63 if (available <= 0 || available / len <= count) { 64 ASSERT(0); 65 } 66 67 void *p = a->beg + padding; 68 a->beg += padding + count * len; 69 return mem_clear(p, 0, count * len); 70 } 71 72 /* NOTE: This performs wrapping of the ring buffer as needed; since a line could be in 73 * progress this must also adjust the start and end of the current line */ 74 static void 75 commit_to_rb(TermView *tv, size len) 76 { 77 ASSERT(len <= tv->log.cap); 78 79 tv->log.widx += len; 80 tv->log.filled += len; 81 82 CLAMP(tv->log.filled, 0, tv->log.cap); 83 if (tv->log.widx >= tv->log.cap) { 84 tv->log.widx -= tv->log.cap; 85 86 size line = tv->lines.widx; 87 tv->lines.buf[line].start -= tv->log.cap; 88 tv->lines.buf[line].end -= tv->log.cap; 89 } 90 91 ASSERT(tv->log.filled >= 0); 92 ASSERT(tv->log.widx >= 0 && tv->log.widx < tv->log.cap); 93 } 94 95 static void 96 line_buf_alloc(LineBuf *lb, Arena *a, u8 *start_position, CellStyle state, size capacity) 97 { 98 lb->cap = capacity; 99 lb->filled = 0; 100 lb->widx = 0; 101 lb->buf = alloc(a, Line, capacity); 102 lb->buf[0].start = start_position; 103 lb->buf[0].end = start_position; 104 lb->buf[0].cursor_state = state; 105 } 106 107 static s8 108 s8alloc(Arena *a, size len) 109 { 110 return (s8){.len = len, .data = alloc(a, u8, len)}; 111 } 112 113 static char * 114 s8_to_cstr(Arena *a, s8 s) 115 { 116 char *cstr = alloc(a, char, s.len + 1); 117 for (size i = 0; i < s.len; i++) 118 cstr[i] = s.data[i]; 119 cstr[s.len] = 0; 120 return cstr; 121 } 122 123 static struct conversion_result 124 i32_from_cstr(char *s, char delim) 125 { 126 struct conversion_result ret = {.status = CR_FAILURE}; 127 i32 scale = 1; 128 129 if (!s || !s[0]) 130 return ret; 131 132 if (s[0] == '-') { 133 s++; 134 scale = -1; 135 } 136 137 for (; *s && *s != delim; s++) { 138 if (!BETWEEN(s[0], '0', '9')) 139 return ret; 140 ret.i *= 10; 141 ret.i += s[0] - '0'; 142 } 143 144 ret.i *= scale; 145 ret.status = CR_SUCCESS; 146 ret.unparsed = (*s == delim) ? s + 1 : s; 147 148 return ret; 149 } 150 151 static s8 152 utf8_encode(u32 cp) 153 { 154 static u8 buf[4]; 155 s8 ret = { .data = buf, .len = -1 }; 156 if (cp < 0x80) { 157 ret.len = 1; 158 buf[0] = cp & 0x7F; 159 } else if (cp < 0x800) { 160 ret.len = 2; 161 buf[0] = ((cp >> 6) & 0x1F) | 0xC0; 162 buf[1] = ((cp >> 0) & 0x3F) | 0x80; 163 } else if (cp < 0x10000) { 164 ret.len = 3; 165 buf[0] = ((cp >> 12) & 0x0F) | 0xE0; 166 buf[1] = ((cp >> 6) & 0x3F) | 0x80; 167 buf[2] = ((cp >> 0) & 0x3F) | 0x80; 168 } else if (cp < 0x200000) { 169 ret.len = 4; 170 buf[0] = ((cp >> 18) & 0x07) | 0xF0; 171 buf[1] = ((cp >> 12) & 0x3F) | 0x80; 172 buf[2] = ((cp >> 6) & 0x3F) | 0x80; 173 buf[3] = ((cp >> 0) & 0x3F) | 0x80; 174 } 175 return ret; 176 } 177 178 #include "extern/utf8_decode.c" 179 #include "extern/wcwidth.c"