vtv.h - vtv-tools - virtual terminal video tools
(HTM) git clone git://bitreich.org/vtv-tools git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/vtv-tools
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
vtv.h (2139B)
---
1 // Single-header library for reading VTV files.
2 //
3 // VTV is an almost trivial format, but there are still a few things
4 // that are convenient to write once and for all (e.g. error
5 // handling).
6 //
7 // Copyright 2023 Troels Henriksen <athas@sigkill.dk>
8 //
9 // See LICENSE file for licensing information.
10
11 #pragma once
12
13 struct vtv {
14 int num_lines;
15 char** lines;
16 };
17
18 void vtv_free(struct vtv* vtv) {
19 for (int i = 0; i < vtv->num_lines; i++) {
20 free(vtv->lines[i]);
21 }
22 free(vtv->lines);
23 free(vtv);
24 }
25
26 // Returns nonzero on error.
27 int vtv_read_lines(FILE* f, char*** lines_out, int *num_lines_out) {
28 size_t n, num_lines = 0, capacity = 10;
29 char** lines = calloc(capacity, sizeof(char*));
30 ssize_t len;
31
32 while ((len = getline(&lines[num_lines], &n, f)) > 0) {
33 lines[num_lines][len-1] = 0; // Strip newline.
34 if (++num_lines == capacity) {
35 capacity *= 2;
36 lines = reallocarray(lines, capacity, sizeof(char*));
37 for (unsigned int i = num_lines; i < capacity; i++) {
38 lines[i] = NULL;
39 }
40 }
41 }
42
43 *lines_out = lines;
44 *num_lines_out = num_lines;
45 return 0;
46 }
47
48 // Show the given frame on the provided file. If there are not enough
49 // lines, show the provided line instead of the missing ones.
50 void vtv_show_frame(struct vtv* vtv,
51 FILE* f,
52 int frame,
53 int lines_per_frame,
54 const char *missing_line) {
55 for (int i = 0; i < lines_per_frame; i++) {
56 int j = frame*lines_per_frame + i;
57 if (j < vtv->num_lines) {
58 fputs(vtv->lines[j], f);
59 fputc('\n', f);
60 } else {
61 fputs(missing_line, f);
62 fputc('\n', f);
63 }
64 }
65 }
66
67 // Returns NULL on error.
68 struct vtv* vtv_read(FILE *f) {
69 struct vtv* vtv = malloc(sizeof(struct vtv));
70 if (vtv_read_lines(f, &vtv->lines, &vtv->num_lines) == 0) {
71 return vtv;
72 } else {
73 free(vtv);
74 return NULL;
75 }
76 }
77
78 // Returns NULL on error.
79 struct vtv* vtv_read_from_file(const char *fname) {
80 FILE *f = fopen(fname, "r");
81 if (f == NULL) {
82 return NULL;
83 } else {
84 struct vtv* vtv = vtv_read(f);
85 fclose(f);
86 return vtv;
87 }
88 }