refs.c (4322B)
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 free(table->id); 56 free(table); 57 } 58 59 static void gopher_refstable_begin(GopherRefsTable* table) { 60 assert(table != NULL); 61 FILE* out = table->out; 62 fprintf(out, "%s\n", table->title); 63 fprintf(out, " %-32.32s", "Name"); 64 fprintf(out, " %-16.16s", "Last commit date"); 65 fprintf(out, " %s\n", "Author"); 66 } 67 68 static void gopher_refstable_add_ref(GopherRefsTable* table, 69 const GitReference* ref) { 70 assert(table != NULL); 71 assert(ref != NULL); 72 GitCommit* commit = ref->commit; 73 FILE* out = table->out; 74 75 fprintf(out, " "); 76 print_gopher_link_padded(out, ref->shorthand, 32, ' '); 77 fprintf(out, " "); 78 print_time_short(out, commit->author_time); 79 fprintf(out, " "); 80 print_gopher_link_padded(out, commit->author_name, 25, '\0'); 81 fprintf(out, "\n"); 82 } 83 84 static void gopher_refstable_end(GopherRefsTable* table) { 85 assert(table != NULL); 86 FILE* out = table->out; 87 fprintf(out, "\n"); 88 } 89 90 GopherRefs* gopher_refs_create(const GitRepo* repo, const FileSystem* fs) { 91 assert(repo != NULL); 92 assert(fs != NULL); 93 GopherRefs* refs = ecalloc(1, sizeof(GopherRefs)); 94 refs->repo = repo; 95 refs->fs = fs; 96 refs->out = fs->fopen("refs.gph", "w"); 97 if (!refs->out) { 98 err(1, "fopen: refs.gph"); 99 } 100 refs->page = gopher_page_create(refs->out, repo, fs, "Refs", ""); 101 return refs; 102 } 103 104 void gopher_refs_free(GopherRefs* refs) { 105 if (!refs) { 106 return; 107 } 108 refs->fs->fclose(refs->out); 109 gopher_page_free(refs->page); 110 gopher_refstable_free(refs->branches); 111 gopher_refstable_free(refs->tags); 112 free(refs); 113 } 114 115 void gopher_refs_begin(GopherRefs* refs) { 116 assert(refs != NULL); 117 gopher_page_begin(refs->page); 118 } 119 120 void gopher_refs_add_ref(GopherRefs* refs, const GitReference* ref) { 121 assert(refs != NULL); 122 assert(ref != NULL); 123 switch (ref->type) { 124 case kReftypeBranch: 125 if (!refs->branches) { 126 refs->branches = 127 gopher_refstable_create("Branches", "branches", refs->out); 128 gopher_refstable_begin(refs->branches); 129 } 130 gopher_refstable_add_ref(refs->branches, ref); 131 break; 132 case kReftypeTag: 133 if (refs->branches) { 134 gopher_refstable_end(refs->branches); 135 gopher_refstable_free(refs->branches); 136 refs->branches = NULL; 137 } 138 if (!refs->tags) { 139 refs->tags = gopher_refstable_create("Tags", "tags", refs->out); 140 gopher_refstable_begin(refs->tags); 141 } 142 gopher_refstable_add_ref(refs->tags, ref); 143 break; 144 } 145 } 146 147 void gopher_refs_end(GopherRefs* refs) { 148 assert(refs != NULL); 149 if (refs->branches) { 150 gopher_refstable_end(refs->branches); 151 gopher_refstable_free(refs->branches); 152 refs->branches = NULL; 153 } 154 if (refs->tags) { 155 gopher_refstable_end(refs->tags); 156 gopher_refstable_free(refs->tags); 157 refs->tags = NULL; 158 } 159 gopher_page_end(refs->page); 160 }