gout

A static git page generator
git clone https://git.bracken.jp/gout.git
Log | Files | Refs | README | LICENSE

refs.c (4452B)


      1 #include "writer/gopher/refs.h"
      2 
      3 #include <assert.h>
      4 #include <err.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 
      8 #include "format.h"
      9 #include "git/commit.h"
     10 #include "utils.h"
     11 #include "writer/gopher/page.h"
     12 
     13 typedef struct {
     14   char* title;
     15   char* id;
     16   FILE* out;
     17 } GopherRefsTable;
     18 
     19 struct GopherRefs {
     20   const GitRepo* repo;
     21   const FileSystem* fs;
     22   FILE* out;
     23   GopherPage* page;
     24   GopherRefsTable* branches;
     25   GopherRefsTable* tags;
     26 };
     27 
     28 static GopherRefsTable* gopher_refstable_create(const char* title,
     29                                                 const char* id,
     30                                                 FILE* out);
     31 static void gopher_refstable_free(GopherRefsTable* table);
     32 static void gopher_refstable_begin(GopherRefsTable* table);
     33 static void gopher_refstable_add_ref(GopherRefsTable* table,
     34                                      const GitReference* ref);
     35 static void gopher_refstable_end(GopherRefsTable* table);
     36 
     37 static GopherRefsTable* gopher_refstable_create(const char* title,
     38                                                 const char* id,
     39                                                 FILE* out) {
     40   assert(title != NULL);
     41   assert(id != NULL);
     42   assert(out != NULL);
     43   GopherRefsTable* table = ecalloc(1, sizeof(GopherRefsTable));
     44   table->title = estrdup(title);
     45   table->id = estrdup(id);
     46   table->out = out;
     47   return table;
     48 }
     49 
     50 static void gopher_refstable_free(GopherRefsTable* table) {
     51   if (!table) {
     52     return;
     53   }
     54   free(table->title);
     55   table->title = NULL;
     56   free(table->id);
     57   table->id = NULL;
     58   free(table);
     59 }
     60 
     61 static void gopher_refstable_begin(GopherRefsTable* table) {
     62   assert(table != NULL);
     63   FILE* out = table->out;
     64   fprintf(out, "%s\n", table->title);
     65   fprintf(out, "  %-32.32s", "Name");
     66   fprintf(out, "  %-16.16s", "Last commit date");
     67   fprintf(out, "  %s\n", "Author");
     68 }
     69 
     70 static void gopher_refstable_add_ref(GopherRefsTable* table,
     71                                      const GitReference* ref) {
     72   assert(table != NULL);
     73   assert(ref != NULL);
     74   GitCommit* commit = ref->commit;
     75   FILE* out = table->out;
     76 
     77   fprintf(out, "  ");
     78   print_gopher_link_padded(out, ref->shorthand, 32, ' ');
     79   fprintf(out, "  ");
     80   print_time_short(out, commit->author_time);
     81   fprintf(out, "  ");
     82   print_gopher_link_padded(out, commit->author_name, 25, '\0');
     83   fprintf(out, "\n");
     84 }
     85 
     86 static void gopher_refstable_end(GopherRefsTable* table) {
     87   assert(table != NULL);
     88   FILE* out = table->out;
     89   fprintf(out, "\n");
     90 }
     91 
     92 GopherRefs* gopher_refs_create(const GitRepo* repo, const FileSystem* fs) {
     93   assert(repo != NULL);
     94   assert(fs != NULL);
     95   GopherRefs* refs = ecalloc(1, sizeof(GopherRefs));
     96   refs->repo = repo;
     97   refs->fs = fs;
     98   refs->out = fs->fopen("refs.gph", "w");
     99   if (!refs->out) {
    100     err(1, "fopen: refs.gph");
    101   }
    102   refs->page = gopher_page_create(refs->out, repo, fs, "Refs", "");
    103   return refs;
    104 }
    105 
    106 void gopher_refs_free(GopherRefs* refs) {
    107   if (!refs) {
    108     return;
    109   }
    110   refs->fs->fclose(refs->out);
    111   refs->out = NULL;
    112   gopher_page_free(refs->page);
    113   refs->page = NULL;
    114   gopher_refstable_free(refs->branches);
    115   refs->branches = NULL;
    116   gopher_refstable_free(refs->tags);
    117   refs->tags = NULL;
    118   free(refs);
    119 }
    120 
    121 void gopher_refs_begin(GopherRefs* refs) {
    122   assert(refs != NULL);
    123   gopher_page_begin(refs->page);
    124 }
    125 
    126 void gopher_refs_add_ref(GopherRefs* refs, const GitReference* ref) {
    127   assert(refs != NULL);
    128   assert(ref != NULL);
    129   switch (ref->type) {
    130     case kReftypeBranch:
    131       if (!refs->branches) {
    132         refs->branches =
    133             gopher_refstable_create("Branches", "branches", refs->out);
    134         gopher_refstable_begin(refs->branches);
    135       }
    136       gopher_refstable_add_ref(refs->branches, ref);
    137       break;
    138     case kReftypeTag:
    139       if (refs->branches) {
    140         gopher_refstable_end(refs->branches);
    141         gopher_refstable_free(refs->branches);
    142         refs->branches = NULL;
    143       }
    144       if (!refs->tags) {
    145         refs->tags = gopher_refstable_create("Tags", "tags", refs->out);
    146         gopher_refstable_begin(refs->tags);
    147       }
    148       gopher_refstable_add_ref(refs->tags, ref);
    149       break;
    150   }
    151 }
    152 
    153 void gopher_refs_end(GopherRefs* refs) {
    154   assert(refs != NULL);
    155   if (refs->branches) {
    156     gopher_refstable_end(refs->branches);
    157     gopher_refstable_free(refs->branches);
    158     refs->branches = NULL;
    159   }
    160   if (refs->tags) {
    161     gopher_refstable_end(refs->tags);
    162     gopher_refstable_free(refs->tags);
    163     refs->tags = NULL;
    164   }
    165   gopher_page_end(refs->page);
    166 }