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 }