Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/sys/src/cmd/ip/httpd/article.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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;
}

void
closepost(Post* p)
{
	if (p == nil)
		return;
	free(p->title);
	free(p->author);
	free(p->body);
	free(p);
}

int
prefixcmp(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);
}

int
parseid(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;
}

int
isson(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
 */
void
insert(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;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.