1 /* 2 * Read a Wiki history file. 3 * It's a title line then a sequence of Wiki files separated by headers. 4 * 5 * Ddate/time 6 * #body 7 * #... 8 * #... 9 * #... 10 * etc. 11 */ 12 13 #include <u.h> 14 #include <libc.h> 15 #include <bio.h> 16 #include <String.h> 17 #include <thread.h> 18 #include "wiki.h" 19 20 static char* 21 Brdwline(void *vb, int sep) 22 { 23 Biobufhdr *b; 24 char *p; 25 26 b = vb; 27 if(Bgetc(b) == '#'){ 28 if(p = Brdline(b, sep)) 29 p[Blinelen(b)-1] = '\0'; 30 return p; 31 }else{ 32 Bungetc(b); 33 return nil; 34 } 35 } 36 37 Whist* 38 Brdwhist(Biobuf *b) 39 { 40 int i, current, conflict, c, n; 41 char *author, *comment, *p, *title; 42 ulong t; 43 Wdoc *w; 44 Whist *h; 45 46 if((p = Brdline(b, '\n')) == nil){ 47 werrstr("short read: %r"); 48 return nil; 49 } 50 51 p[Blinelen(b)-1] = '\0'; 52 p = strcondense(p, 1); 53 title = estrdup(p); 54 55 w = nil; 56 n = 0; 57 t = -1; 58 author = nil; 59 comment = nil; 60 conflict = 0; 61 current = 0; 62 while((c = Bgetc(b)) != Beof){ 63 if(c != '#'){ 64 p = Brdline(b, '\n'); 65 if(p == nil) 66 break; 67 p[Blinelen(b)-1] = '\0'; 68 69 switch(c){ 70 case 'D': 71 t = strtoul(p, 0, 10); 72 break; 73 case 'A': 74 free(author); 75 author = estrdup(p); 76 break; 77 case 'C': 78 free(comment); 79 comment = estrdup(p); 80 break; 81 case 'X': 82 conflict = 1; 83 } 84 } else { /* c=='#' */ 85 Bungetc(b); 86 if(n%8 == 0) 87 w = erealloc(w, (n+8)*sizeof(w[0])); 88 w[n].time = t; 89 w[n].author = author; 90 w[n].comment = comment; 91 comment = nil; 92 author = nil; 93 w[n].wtxt = Brdpage(Brdwline, b); 94 w[n].conflict = conflict; 95 if(w[n].wtxt == nil) 96 goto Error; 97 if(!conflict) 98 current = n; 99 n++; 100 conflict = 0; 101 t = -1; 102 } 103 } 104 if(w==nil) 105 goto Error; 106 107 free(comment); 108 free(author); 109 h = emalloc(sizeof *h); 110 h->title = title; 111 h->doc = w; 112 h->ndoc = n; 113 h->current = current; 114 incref(h); 115 setmalloctag(h, getcallerpc(&b)); 116 return h; 117 118 Error: 119 free(title); 120 free(author); 121 free(comment); 122 for(i=0; i<n; i++){ 123 free(w[i].author); 124 free(w[i].comment); 125 freepage(w[i].wtxt); 126 } 127 free(w); 128 return nil; 129 } 130 131