shithub: fsgen

ref: 17039fc93f8eb42fe58797dee5082f486616a6a6
dir: /files.c/

View raw version
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"

VFile *files = nil;

static char**
parsepath(char *path)
{
	char **args;
	char *s;
	int numparts = 1, n;
	
	if (path[1] == 0) {
		args = mallocz(2, 1);
		args[0] = mallocz(1, 1);
		args[0][0] = 0;
		args[1] = nil;
		return args;
	}
	
	for (s = path; *s; s++) {
		if (*s == '/')
			numparts++;
	}
	
	/* root dir, each directory part, ending nil */
	args = mallocz(numparts+1, 1);
	args[numparts] = nil;
	s = strdup(path);
	n = getfields(s, args, numparts, 0, "/");
	
	assert(s == args[0]);
	if (n == numparts)
		return args;
	free(args);
	free(s);
	werrstr("invalid path");
	return nil;
}

VFile*
addfile(char *path)
{
	VFile *old;
	old = getfile(path);
	if (old)
		return old;
	
	if (!files) {
		files = mallocz(sizeof(VFile), 1);
	} else {
		old = files;
		files = mallocz(sizeof(VFile), 1);
		files->next = old;
	}
	files->path = strdup(path);
	files->parts = parsepath(path);
	if (!files->parts)
		return nil;
	return files;
}

VFile*
getfile(char *path)
{
	VFile *v;
	
	for (v = files; v; v = v->next)
		if (strcmp(v->path, path) == 0)
			return v;
	werrstr("file not found: %s", path);
	return nil;
}

void
foreachfile(void (*f)(VFile*,void*), void *aux)
{
	VFile *vf;
	
	for (vf = files; vf; vf = vf->next)
		f(vf, aux);
}

int
getnfiles()
{
	int n = 0;
	VFile *v;
	
	for (v = files; v; v = v->next)
		n++;
	
	return n;
}

static int
Vfmt(Fmt *f)
{
	VFile *v;
	v = va_arg(f->args, VFile*);
	return fmtprint(f, "%s (%s%s%s)", v->path,
		v->isdir ? "D," : "",
		v->hasread ? "R," : "",
		v->haswrite ? "W" : ""
	);
}

void
vfileinit()
{
	fmtinstall('V', Vfmt);
}