ref: 8291e90f0700652c6f3a3dce408244a67600ad46
dir: /piper/piper.c/
#include <u.h> #include <libc.h> #include <thread.h> #include <bio.h> #include "piper.h" typedef struct Group Group; struct Group { char *path; Synth *synth; void **aux; int numaux; int clone; }; static Group *groups; static int numgroups; static Synth *synths[] = { &ay_3_8910, &kick_drum, }; static void usage(void) { print("usage: %s DIR...\n", argv0); threadexitsall("usage"); } static char * parse(char *s, Group *g) { Cmd c; char *e, *path, tmp[8]; void *aux; int i, n; for (i = 1; s[i] != 0 && s[i] != ';'; i++); e = s[i] == 0 ? nil : s + i + 1; s[i] = 0; if (g != nil) { s++; i = i36(*s); while (i >= g->numaux) { /* instance needs to be created */ seek(g->clone, 0, 0); if ((n = read(g->clone, tmp, sizeof(tmp))) < 1) sysfatal("clone failed"); tmp[n] = 0; if ((path = smprint("%s/%s/%s", g->path, tmp, g->synth->name)) == nil) sysfatal("memory"); if ((aux = g->synth->alloc(path)) == nil) return e; if ((g->aux = realloc(g->aux, sizeof(void*)*(g->numaux+1))) == nil) sysfatal("memory"); g->aux[g->numaux++] = aux; } aux = g->aux[i]; memset(&c, 0, sizeof(c)); g->synth->cmd(aux, &c); } return e; } void threadmain(int argc, char **argv) { char *s, t[256]; Synth *synth; Biobuf *b; int i, j, n; ARGBEGIN{ default: usage(); }ARGEND; if (argc < 1) usage(); quotefmtinstall(); /* go through all groups */ for (i = 0; i < argc; i++) { /* search for specific synth handler by its name */ s = smprint("%s/metadata", argv[i]); if ((b = Bopen(s, OREAD)) == nil) sysfatal("%r"); free(s); synth = nil; while ((s = Brdline(b, '\n')) != nil) { if (strncmp(s, "name\t", 5) == 0) { s[Blinelen(b)-1] = 0; for (j = 0; j < nelem(synths) && strcmp(synths[j]->name, s+5) != 0; j++); if (j >= nelem(synths)) sysfatal("unknown synth %q\n", s+5); if ((groups = realloc(groups, sizeof(Group)*(numgroups+1))) == nil) sysfatal("memory"); synth = synths[j]; memset(&groups[numgroups], 0, sizeof(Group)); if ((s = smprint("%s/clone", argv[i])) == nil) sysfatal("memory"); if ((groups[numgroups].clone = open(s, OREAD)) < 0) sysfatal("%r"); free(s); groups[numgroups].path = argv[i]; groups[numgroups++].synth = synth; break; } } Bterm(b); if (synth == nil) sysfatal("no name set in %s/metadata", argv[i]); } for (;;) { if ((n = read(0, t, sizeof(t)-1)) < 1) break; t[n] = 0; for (s = t; s != nil && *s;) { i = i36(s[0]); s = parse(s, i < numgroups ? &groups[i] : nil); } } threadexitsall(nil); }