debug.c (3592B)
1 #include "util.h" 2 3 static Cursor 4 simulate_line(Term *t, Line *line) 5 { 6 Cursor saved_cursor = t->cursor; 7 s8 l = line_to_s8(line, &t->views[t->view_idx].log); 8 9 t->cursor.style = line->cursor_state; 10 11 while (l.len) { 12 u32 cp; 13 if (line->has_unicode) cp = get_utf8(&l); 14 else cp = get_ascii(&l); 15 16 u32 advance = g_tabstop - (t->cursor.pos.x % g_tabstop); 17 18 switch (cp) { 19 case 0x1B: check_if_escape_moves_cursor(t, &l); break; 20 case '\r': t->cursor.pos.x = 0; break; 21 case '\n': cursor_move_to(t, t->cursor.pos.y + 1, t->cursor.pos.x); break; 22 case '\t': cursor_move_to(t, t->cursor.pos.y, t->cursor.pos.x + advance); break; 23 case '\b': cursor_move_to(t, t->cursor.pos.y, t->cursor.pos.x - 1); break; 24 case '\a': break; 25 default: cursor_move_to(t, t->cursor.pos.y, t->cursor.pos.x + 1); break; 26 } 27 } 28 29 Cursor result = t->cursor; 30 t->cursor = saved_cursor; 31 32 return result; 33 } 34 35 static void 36 fput_cursor_info(FILE *f, Cursor c) 37 { 38 fprintf(f, "\tFG: 0x%08x\n", c.style.fg.rgba); 39 fprintf(f, "\tBG: 0x%08x\n", c.style.bg.rgba); 40 fprintf(f, "\tAttr: 0x%08x\n", c.style.attr); 41 fprintf(f, "\tPos: {%d, %d}\n", c.pos.y, c.pos.x); 42 } 43 44 static void 45 fput_line_info(FILE *f, Term *t, Line *l) 46 { 47 Cursor start = t->cursor; 48 start.style = l->cursor_state; 49 fprintf(f, "Line Info:\n"); 50 fprintf(f, "\tLength: %ld\n", line_length(l)); 51 fprintf(f, "\tHas Unicode: %d\n", l->has_unicode); 52 fput_cursor_info(f, start); 53 Cursor end = simulate_line(t, l); 54 fprintf(f, "After Line Cursor State:\n"); 55 fput_cursor_info(f, end); 56 } 57 58 static void 59 dump_last_line_to_file(Term *t) 60 { 61 char *fname = "last_line.bin"; 62 FILE *f = fopen(fname, "w"); 63 if (!f) return; 64 65 printf("dumping line to %s\n", fname); 66 67 TermView *tv = t->views + t->view_idx; 68 fputs("Line Idx -1:\n", f); 69 Line *line = tv->lines.buf + get_line_idx(&tv->lines, -1); 70 s8 l = line_to_s8(line, &tv->log); 71 fput_line_info(f, t, line); 72 fwrite(l.data, 1, l.len, f); 73 74 fputs("\nLine Idx 0:\n", f); 75 line = tv->lines.buf + get_line_idx(&tv->lines, 0); 76 l = line_to_s8(line, &tv->log); 77 fput_line_info(f, t, line); 78 fwrite(l.data, 1, l.len, f); 79 80 fclose(f); 81 } 82 83 static void 84 fput_cell(FILE *f, Cell *c) 85 { 86 s8 s = utf8_encode(c->cp); 87 fwrite(s.data, 1, s.len, f); 88 } 89 90 static void 91 dump_fb_to_file(Term *t) 92 { 93 TermView *tv = t->views + t->view_idx; 94 char *fname = "fb.bin"; 95 FILE *f = fopen(fname, "w"); 96 if (!f) return; 97 printf("dumping fb to %s\n", fname); 98 for (u32 r = 0; r < t->size.h; r++) { 99 for (u32 c = 0; c < t->size.w; c++) 100 fput_cell(f, &tv->fb.rows[r][c]); 101 fputc('\n', f); 102 } 103 fclose(f); 104 } 105 106 static void 107 dump_glyph_cache_to_file(FontAtlas *fa) 108 { 109 char *fname = "fa.text"; 110 FILE *f = fopen(fname, "w"); 111 if (!f) return; 112 printf("dumping glyph cache to %s\n", fname); 113 114 GlyphCache *gc = &fa->glyph_cache; 115 GlyphCacheStats stats = get_and_clear_glyph_cache_stats(gc); 116 fputs("Stats:\n", f); 117 fprintf(f, "hit: %u\n", stats.hit_count); 118 fprintf(f, "miss: %u\n", stats.miss_count); 119 fprintf(f, "recycle: %u\n", stats.recycle_count); 120 121 u32 count = 0; 122 fputs("\nChain:\n", f); 123 for (u32 i = gc->glyphs[0].next; i; i = gc->glyphs[i].next) { 124 count++; 125 fprintf(f, "%u -> ", i); 126 } 127 128 fprintf(f, "\n\ncount: %u\n\n", count); 129 130 fputs("Glyphs:\n", f); 131 for (u32 i = gc->glyphs[0].next; i; i = gc->glyphs[i].next) { 132 u32 cp = gc->glyphs[i].cp; 133 s8 encoded = utf8_encode(cp); 134 fwrite(encoded.data, 1, encoded.len, f); 135 fputs(" -> ", f); 136 } 137 138 fclose(f); 139 }