shithub: fsgen

ref: a976de46123b51045a1ea123ad452e8465e71b08
dir: /vars.c/

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

typedef struct Var Var;
struct Var {
	char *name;
	Var *next;
};

Var *vars = nil;

static int
hasvar(char *name)
{
	Var *v;
	
	for (v = vars; v; v = v->next)
		if (v->name == name)
			return 1;
	return 0;
}

static void
caddvar(char *name)
{
	Var *v;
	char buf[32];
	
	strcpy(buf, name);
	buf[strlen(name)-1] = 0;
	
	if (!vars) {
		vars = mallocz(sizeof(Var), 1);
		vars->name = buf+1;
		return;
	}
	if (hasvar(name))
		return;
	v = vars;
	vars = mallocz(sizeof(Var), 1);
	vars->name = buf+1;
	vars->next = v;
}

static void
collectvars(VFile *f, void*)
{
	char **a;
	char *s;
	int n;
	
	for (a = f->parts; *a; a++) {
		s = *a;
		if (s[0] == 0)
			continue;
		n = strlen(s) - 1;
		if (!(s[0] == '{' && s[n] == '}'))
			continue;
		caddvar(s);
	}
}

void
printauxvars()
{
	Var *v;
	char buf[32];
	char *s;
	
	foreachfile(collectvars, nil);
	
	print(
	"typedef struct FileAux FileAux;\n"
	"struct FileAux {\n"
	);
	
	if (!vars)
		print("	int dummy;\n");
	
	for (v = vars; v; v = v->next) {
		print("	char *%s;\n", v->name);
	}
	
	print("};\n\n");
	
	
	// TODO: secure array out of bounds!
	print("static uvlong\ngetqidhash(Fid *fid)\n{\n");
	print(
	"	FileAux *f = fid->aux;\n"
	"	char buf[1024];\n"
	"	uchar dig[SHA1dlen];\n"
	"	char *s;\n"
	"	uvlong hash;\n");
	
	print("	if (!f) return 0;\n");
	
	print("\n	s = buf;\n");
	for (v = vars; v; v = v->next) {
		strcpy(buf, v->name+1);
		s = strchr(buf, '}');
		
		print(
		"	if (f->%s) {\n"
		"		strcpy(s, f->%s);\n"
		"		s += strlen(f->%s);\n"
		"		*s = '/';\n"
		"		s++;\n"
		"		*s = 0;\n"
		"	}\n",
		v->name, v->name, v->name);
	}
	
	print(
	"	sha1((uchar*)buf, sizeof(buf), dig, nil);\n"
	"	memcpy(&hash, dig, sizeof(hash));\n"
	);
	
	print("	return hash & ((0x1<<(SHIFT+1))-1);\n}\n\n");
	
	
	/* clone function */
	print("/* speak: clone wars */\n"
	"static void\n"
	"clonevars(FileAux *src, FileAux *dst)\n{\n");
	
	for (v = vars; v; v = v->next) {
		strcpy(buf, v->name+1);
		s = strchr(buf, '}');
		
		print(
		"	if (src->%s) dst->%s = strdup(src->%s);\n",
		v->name, v->name, v->name);
	}
	
	print("}\n\n");
	
	
	/* setvar function */
	print(
	"static void\n"
	"setvar(FileAux *a, char *name, char *value)\n{\n");
	
	for (v = vars; v; v = v->next) {
		print(
		"	if (strcmp(name, \"%s\") == 0) { a->%s = strdup(value); return; }\n",
		v->name, v->name);
	}
	
	print("}\n\n");
}