Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/sys/src/cmd/bns/names.c

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


/*
 * Path names.
 */
#include <u.h>
#include <libc.h>
#include <fcall.h>
#include "names.h"

enum {
	Incr = 128,
};

extern void* emalloc(long);
extern void* erealloc(void*, long);


Name*
n_new(void)
{
	Name*	n;

	n = emalloc(sizeof(Name));
	n->elems = emalloc(MAXWELEM * sizeof(char*));
	memset(n->elems, 0, MAXWELEM*sizeof(char*));
	n->aelems= MAXWELEM;
	n->nelems= 0;
	n->base = emalloc(Incr);
	n->end = n->base + Incr;
	n->ptr = n->base;
	*n->ptr = 0;
	return n;
}

int
namefmt(Fmt* f)
{
	Name*	n;
	char*	buf;
	int	bufsz;
	char*	s;
	int	i;
	int	r;

	n = va_arg(f->args, Name*);
	if (!n)
		return fmtprint(f, "nil name");
	bufsz = n->ptr - n->base + 1;
	if (bufsz == 1)
		bufsz++;	// be sure we can keep "/" at least
	buf = emalloc(bufsz);
	s = buf;
	s[0] = '/';
	s[1] = 0;
	for (i = 0; i < n->nelems; i++)
		s = seprint(s, buf + bufsz, "/%s", n->elems[i]);
	r =  fmtprint(f, "%s", buf);
	free(buf);
	return r;
}

void
n_reset(Name* n)
{
	n->nelems = 0;
	n->ptr = n->base;
}

void
n_append(Name* n, char* s)
{
	int	slen;
	int	nlen;
	int	alen;
	char*	nbase;
	int	i;

	slen = strlen(s);
	nlen = n->ptr - n->base;
	alen = n->end - n->base;
	while (alen < nlen + slen + 1){	// + 1 for zero
		nbase = erealloc(n->base, alen + Incr);
		alen += Incr;
		n->end = nbase + alen;
		n->ptr = nbase + nlen;
		for (i = 0; i < n->nelems && n->elems[i] != nil; i++)
			n->elems[i] = nbase + (n->elems[i] - n->base);
		n->base = n->base;
	}
	if (n->nelems == n->aelems){
		n->aelems += MAXWELEM;
		n->elems = erealloc(n->elems, n->aelems * sizeof(char*));
	}
	n->elems[n->nelems++] = n->ptr;
	strcpy(n->ptr, s);
	n->ptr += slen;
	*n->ptr++ = 0;
}

void
n_dotdot(Name* n)
{
	assert(n->nelems > 0);
	n->ptr = n->elems[--n->nelems];
}

void
n_getpos(Name* n, int* a, int* b)
{
	*a = n->nelems;
	*b = n->ptr - n->base;
}

void
n_setpos(Name* n, int a, int b)
{
	n->nelems = a;
	n->ptr = n->base + b;
	assert(n->ptr >= n->base && n->ptr < n->end);
}

void
n_cat(Name* cn, Name* n)
{
	int	i;

	for (i = 0; i < n->nelems; i++)
		n_append(cn, n->elems[i]);
}

int
n_eq(Name* n1, Name* n2)
{
	int	i;

	if (n1 == nil || n2 == nil)
		return n1 == n2;
	if (n1->nelems != n2->nelems)
		return 0;
	// paths use to differ near the end.
	// check it out in reverse order.
	for (i = n1->nelems-1; i >=0; i--)
		if (strcmp(n1->elems[i], n2->elems[i]))
			return 0;
	return 1;
}
	
void
n_free(Name* n)
{
	free(n->base);
	free(n->elems);
	free(n);
}

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.