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 }