19a747e4fSDavid du Colombier /*
29a747e4fSDavid du Colombier * Read a Wiki history file.
39a747e4fSDavid du Colombier * It's a title line then a sequence of Wiki files separated by headers.
49a747e4fSDavid du Colombier *
59a747e4fSDavid du Colombier * Ddate/time
69a747e4fSDavid du Colombier * #body
79a747e4fSDavid du Colombier * #...
89a747e4fSDavid du Colombier * #...
99a747e4fSDavid du Colombier * #...
109a747e4fSDavid du Colombier * etc.
119a747e4fSDavid du Colombier */
129a747e4fSDavid du Colombier
139a747e4fSDavid du Colombier #include <u.h>
149a747e4fSDavid du Colombier #include <libc.h>
159a747e4fSDavid du Colombier #include <bio.h>
169a747e4fSDavid du Colombier #include <String.h>
179a747e4fSDavid du Colombier #include <thread.h>
189a747e4fSDavid du Colombier #include "wiki.h"
199a747e4fSDavid du Colombier
209a747e4fSDavid du Colombier static char*
Brdwline(void * vb,int sep)219a747e4fSDavid du Colombier Brdwline(void *vb, int sep)
229a747e4fSDavid du Colombier {
239a747e4fSDavid du Colombier Biobufhdr *b;
249a747e4fSDavid du Colombier char *p;
259a747e4fSDavid du Colombier
269a747e4fSDavid du Colombier b = vb;
279a747e4fSDavid du Colombier if(Bgetc(b) == '#'){
289a747e4fSDavid du Colombier if(p = Brdline(b, sep))
299a747e4fSDavid du Colombier p[Blinelen(b)-1] = '\0';
309a747e4fSDavid du Colombier return p;
319a747e4fSDavid du Colombier }else{
329a747e4fSDavid du Colombier Bungetc(b);
339a747e4fSDavid du Colombier return nil;
349a747e4fSDavid du Colombier }
359a747e4fSDavid du Colombier }
369a747e4fSDavid du Colombier
379a747e4fSDavid du Colombier Whist*
Brdwhist(Biobuf * b)389a747e4fSDavid du Colombier Brdwhist(Biobuf *b)
399a747e4fSDavid du Colombier {
409a747e4fSDavid du Colombier int i, current, conflict, c, n;
419a747e4fSDavid du Colombier char *author, *comment, *p, *title;
429a747e4fSDavid du Colombier ulong t;
439a747e4fSDavid du Colombier Wdoc *w;
449a747e4fSDavid du Colombier Whist *h;
459a747e4fSDavid du Colombier
469a747e4fSDavid du Colombier if((p = Brdline(b, '\n')) == nil){
479a747e4fSDavid du Colombier werrstr("short read: %r");
489a747e4fSDavid du Colombier return nil;
499a747e4fSDavid du Colombier }
509a747e4fSDavid du Colombier
519a747e4fSDavid du Colombier p[Blinelen(b)-1] = '\0';
529a747e4fSDavid du Colombier p = strcondense(p, 1);
539a747e4fSDavid du Colombier title = estrdup(p);
549a747e4fSDavid du Colombier
559a747e4fSDavid du Colombier w = nil;
569a747e4fSDavid du Colombier n = 0;
579a747e4fSDavid du Colombier t = -1;
589a747e4fSDavid du Colombier author = nil;
599a747e4fSDavid du Colombier comment = nil;
609a747e4fSDavid du Colombier conflict = 0;
619a747e4fSDavid du Colombier current = 0;
629a747e4fSDavid du Colombier while((c = Bgetc(b)) != Beof){
639a747e4fSDavid du Colombier if(c != '#'){
649a747e4fSDavid du Colombier p = Brdline(b, '\n');
659a747e4fSDavid du Colombier if(p == nil)
669a747e4fSDavid du Colombier break;
679a747e4fSDavid du Colombier p[Blinelen(b)-1] = '\0';
689a747e4fSDavid du Colombier
699a747e4fSDavid du Colombier switch(c){
709a747e4fSDavid du Colombier case 'D':
719a747e4fSDavid du Colombier t = strtoul(p, 0, 10);
729a747e4fSDavid du Colombier break;
739a747e4fSDavid du Colombier case 'A':
749a747e4fSDavid du Colombier free(author);
759a747e4fSDavid du Colombier author = estrdup(p);
769a747e4fSDavid du Colombier break;
779a747e4fSDavid du Colombier case 'C':
789a747e4fSDavid du Colombier free(comment);
799a747e4fSDavid du Colombier comment = estrdup(p);
809a747e4fSDavid du Colombier break;
819a747e4fSDavid du Colombier case 'X':
829a747e4fSDavid du Colombier conflict = 1;
839a747e4fSDavid du Colombier }
849a747e4fSDavid du Colombier } else { /* c=='#' */
859a747e4fSDavid du Colombier Bungetc(b);
869a747e4fSDavid du Colombier if(n%8 == 0)
879a747e4fSDavid du Colombier w = erealloc(w, (n+8)*sizeof(w[0]));
889a747e4fSDavid du Colombier w[n].time = t;
899a747e4fSDavid du Colombier w[n].author = author;
909a747e4fSDavid du Colombier w[n].comment = comment;
91*af2e6ba6SDavid du Colombier comment = nil;
92*af2e6ba6SDavid du Colombier author = nil;
939a747e4fSDavid du Colombier w[n].wtxt = Brdpage(Brdwline, b);
949a747e4fSDavid du Colombier w[n].conflict = conflict;
959a747e4fSDavid du Colombier if(w[n].wtxt == nil)
969a747e4fSDavid du Colombier goto Error;
979a747e4fSDavid du Colombier if(!conflict)
989a747e4fSDavid du Colombier current = n;
999a747e4fSDavid du Colombier n++;
1009a747e4fSDavid du Colombier conflict = 0;
1019a747e4fSDavid du Colombier t = -1;
1029a747e4fSDavid du Colombier }
1039a747e4fSDavid du Colombier }
1049a747e4fSDavid du Colombier if(w==nil)
1059a747e4fSDavid du Colombier goto Error;
1069a747e4fSDavid du Colombier
1079a747e4fSDavid du Colombier free(comment);
1089a747e4fSDavid du Colombier free(author);
1099a747e4fSDavid du Colombier h = emalloc(sizeof *h);
1109a747e4fSDavid du Colombier h->title = title;
1119a747e4fSDavid du Colombier h->doc = w;
1129a747e4fSDavid du Colombier h->ndoc = n;
1139a747e4fSDavid du Colombier h->current = current;
1149a747e4fSDavid du Colombier incref(h);
115*af2e6ba6SDavid du Colombier setmalloctag(h, getcallerpc(&b));
1169a747e4fSDavid du Colombier return h;
1179a747e4fSDavid du Colombier
1189a747e4fSDavid du Colombier Error:
1199a747e4fSDavid du Colombier free(title);
1209a747e4fSDavid du Colombier free(author);
1219a747e4fSDavid du Colombier free(comment);
122*af2e6ba6SDavid du Colombier for(i=0; i<n; i++){
123*af2e6ba6SDavid du Colombier free(w[i].author);
124*af2e6ba6SDavid du Colombier free(w[i].comment);
1259a747e4fSDavid du Colombier freepage(w[i].wtxt);
126*af2e6ba6SDavid du Colombier }
1279a747e4fSDavid du Colombier free(w);
1289a747e4fSDavid du Colombier return nil;
1299a747e4fSDavid du Colombier }
1309a747e4fSDavid du Colombier
131