Seedbox v0.1 + firmware, generic kit/synth, ROOT/SCALE pages
Some checks failed
check / check (push) Has been cancelled
Some checks failed
check / check (push) Has been cancelled
First commit of the repo. Contents beyond the v0.1 simulator and layout: - Full Pico 2 W firmware (firmware/app, drivers, engine port, host test). - BANK page and 404 mode A/B removed; learned pads play exactly what was learned. - 404/MiniFreak renamed to KIT/SYNTH throughout (jacks, code, sim, docs, layout labels; wiring rebuilt). - ROLL returns to page select after a re-roll; a freshly learned track turns on. - LCD contrast 66. - ROOT and SCALE pages: 21 scales, AUTO = the seed picks; global and sticky. Intended music change: the scale table grew from 8 to 21 and AUTO picks from all of them, so every seed's scale changed. Vectors regenerated with npm run vectors, plus new key-override cases. Flash record is now version 2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
99
firmware/test/json.c
Normal file
99
firmware/test/json.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "json.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *p;
|
||||
static int bad;
|
||||
|
||||
static void ws(void){ while(*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') p++; }
|
||||
static void *xcalloc(size_t n, size_t s){ void *r = calloc(n, s); if(!r){ fprintf(stderr, "out of memory\n"); exit(2); } return r; }
|
||||
|
||||
static char *parse_str(void){
|
||||
const char *s = ++p;
|
||||
char *out, *o;
|
||||
while(*p && *p != '"'){ if(*p == '\\' && p[1]) p++; p++; }
|
||||
if(*p != '"'){ bad = 1; return NULL; }
|
||||
out = o = xcalloc((size_t)(p - s) + 1, 1);
|
||||
for(; s < p; s++){ if(*s == '\\') s++; *o++ = *s; }
|
||||
p++;
|
||||
return out;
|
||||
}
|
||||
static jval *parse_val(void);
|
||||
static void add(jval *v, jval *item){
|
||||
v->items = realloc(v->items, sizeof(jval *) * (size_t)(v->n + 1));
|
||||
if(!v->items){ fprintf(stderr, "out of memory\n"); exit(2); }
|
||||
v->items[v->n++] = item;
|
||||
}
|
||||
static jval *parse_val(void){
|
||||
jval *v = xcalloc(1, sizeof *v);
|
||||
ws();
|
||||
if(*p == '{'){
|
||||
v->type = J_OBJ; p++; ws();
|
||||
if(*p == '}'){ p++; return v; }
|
||||
for(;;){
|
||||
char *k; jval *item;
|
||||
ws(); if(*p != '"'){ bad = 1; return v; }
|
||||
k = parse_str(); ws();
|
||||
if(*p != ':'){ bad = 1; free(k); return v; }
|
||||
p++;
|
||||
item = parse_val(); item->key = k; add(v, item);
|
||||
ws(); if(*p == ','){ p++; continue; }
|
||||
if(*p == '}'){ p++; return v; }
|
||||
bad = 1; return v;
|
||||
}
|
||||
}
|
||||
if(*p == '['){
|
||||
v->type = J_ARR; p++; ws();
|
||||
if(*p == ']'){ p++; return v; }
|
||||
for(;;){
|
||||
add(v, parse_val());
|
||||
ws(); if(*p == ','){ p++; continue; }
|
||||
if(*p == ']'){ p++; return v; }
|
||||
bad = 1; return v;
|
||||
}
|
||||
}
|
||||
if(*p == '"'){ v->type = J_STR; v->str = parse_str(); return v; }
|
||||
if(!strncmp(p, "true", 4)){ v->type = J_BOOL; v->num = 1; p += 4; return v; }
|
||||
if(!strncmp(p, "false", 5)){ v->type = J_BOOL; v->num = 0; p += 5; return v; }
|
||||
if(!strncmp(p, "null", 4)){ v->type = J_NULL; p += 4; return v; }
|
||||
if(*p == '-' || (*p >= '0' && *p <= '9')){
|
||||
char *end;
|
||||
v->type = J_NUM; v->num = strtoll(p, &end, 10);
|
||||
if(*end == '.' || *end == 'e' || *end == 'E') bad = 1; /* the vectors are integer-only */
|
||||
p = end; return v;
|
||||
}
|
||||
bad = 1; return v;
|
||||
}
|
||||
|
||||
jval *json_parse_file(const char *path){
|
||||
FILE *f = fopen(path, "rb");
|
||||
long n;
|
||||
char *buf;
|
||||
jval *v;
|
||||
if(!f) return NULL;
|
||||
fseek(f, 0, SEEK_END); n = ftell(f); fseek(f, 0, SEEK_SET);
|
||||
buf = xcalloc((size_t)n + 1, 1);
|
||||
if(fread(buf, 1, (size_t)n, f) != (size_t)n){ fclose(f); free(buf); return NULL; }
|
||||
fclose(f);
|
||||
p = buf; bad = 0;
|
||||
v = parse_val();
|
||||
ws();
|
||||
if(*p) bad = 1;
|
||||
free(buf);
|
||||
if(bad){ json_free(v); return NULL; }
|
||||
return v;
|
||||
}
|
||||
jval *json_get(const jval *o, const char *key){
|
||||
int i;
|
||||
if(!o || o->type != J_OBJ) return NULL;
|
||||
for(i = 0; i < o->n; i++) if(!strcmp(o->items[i]->key, key)) return o->items[i];
|
||||
return NULL;
|
||||
}
|
||||
jval *json_at(const jval *a, int i){ return (a && (a->type == J_ARR || a->type == J_OBJ) && i >= 0 && i < a->n) ? a->items[i] : NULL; }
|
||||
void json_free(jval *v){
|
||||
int i;
|
||||
if(!v) return;
|
||||
for(i = 0; i < v->n; i++) json_free(v->items[i]);
|
||||
free(v->items); free(v->str); free(v->key); free(v);
|
||||
}
|
||||
Reference in New Issue
Block a user