henesyinit from lsubb0c8bdb6 years agoHistory
198 lines · 3.0 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include <ctype.h>#include "article.h" Post*newpost(void){	Post*	p; 	p = malloc(sizeof(Post));	memset(p, 0, sizeof(p));	return p;} voidclosepost(Post* p){	if (p == nil)		return;	free(p->title);	free(p->author);	free(p->body);	free(p);} intprefixcmp(int top[], int p[], int n){	int	i; 	for (i = 0; i < Nids && i < n; i++)		if (top[i] != p[i])			return 1;	return 0;} char*id2str(int ids[], int n){	char buf[100];	char*	s;	int	i; 	s = buf;	for (i = 0; i < n; i++)		if (i == 0)			s = seprint(s, buf+sizeof(buf), "%d", ids[i]);		else			s = seprint(s, buf+sizeof(buf), ".%d", ids[i]);	return strdup(buf);} intparseid(char* buf, int ids[], int max){	char*	toks[Nids+1];	int	i;	int	n; 	n = getfields(buf, toks, nelem(toks), 0, ".");	if (n > Nids || n > max)		n = 0;	for (i = 0; i < n; i++)		ids[i] = atoi(toks[i]);	return n;} intisson(Post* t, Post* p){	if (t != nil && p != nil && t->nids == p->nids - 1)	if (!prefixcmp(t->ids, p->ids, t->nids))		return 1;	return 0;}  	char*seprintpost(char* s, char* e, Post* p){	char*	is; 	is = id2str(p->ids, p->nids);	s = seprint(s, e, "%s", is);	free(is);	s = seprint(s, e, "\n%s\n", p->title);	s = seprint(s, e, "%s\n", p->author);	return seprint(s, e, "%s%c", p->body, Eop);}   Post*readpost(Biobuf* b){	Post*	p;	char*	ln; 	ln = Brdstr(b, '\n', 1);	if (ln == nil)		return nil; 	p = malloc(sizeof(Post));	memset(p, 0, sizeof(Post));	p->nids = parseid(ln, p->ids, Nids);	free(ln);	p->title = Brdstr(b, '\n', 1);	p->author= Brdstr(b, '\n', 1);	p->body = Brdstr(b, Eop, 1);	if (p->nids == 0 || !p->title || !p->author || !p->body){		fprint(2, "null post member\n");		closepost(p);		return nil;	} else		return p;} /* * Top ids[] is a prefix of p ids[] * we descend evaluating more into the prefix * until we have a single element to evaluate */voidinsert(Post* top, Post* p){	int	i;	Post*	s;	Post*	nxt; 	while(!isson(top, p)){		nxt = nil;		for (i = 0; i < top->nsons; i++){			s = top->sons[i];			if (s != nil)			if (!prefixcmp(s->ids, p->ids, s->nids)){				nxt = s;				break;			}		}		if (nxt == nil){			fprint(2, "warning: parent %s\n", top->title);			fprint(2, "warning: son w/o parent %s\n", p->title);			return;		}		top = nxt;	}	if (top->nsons == Nsons){		fprint(2, "warning: Nsons reached\n");		return;	}	top->sons[top->nsons++] = p;} Post*lookup(Post* p, int ids[], int nids){	int	i;	Post*	s;	Post*	nxt;  	while(p != nil && !(p->nids == nids && !prefixcmp(p->ids, ids, nids))){		nxt = nil;		for (i = 0; i < p->nsons; i++){			s = p->sons[i];			if (s != nil)			if (!prefixcmp(s->ids, ids, s->nids)){				nxt = s;				break;			}		}		p = nxt;	}	return p;} Post*readarticle(Biobuf* bin, int* n){	Post*	top;	Post*	p; 	if (n != nil)		*n = 0;	top = readpost(bin);	while(top != nil){		if (n != nil)			*n = *n + 1;		p = readpost(bin);		if (p == nil)			break;		insert(top, p);	}	return top;}