ref: a976de46123b51045a1ea123ad452e8465e71b08
dir: /vars.c/
#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");
}