diff -urN midi_prog-/Makefile midi_prog/Makefile --- midi_prog-/Makefile Thu Apr 16 00:00:00 2015 +++ midi_prog/Makefile Fri Apr 17 00:00:00 2015 @@ -1,6 +1,6 @@ CC = gcc LIB = -lm -lpthread -L../cui -lcui -TARG = prog55 +TARG = prog56 OBJS = main.o vcf.o ch.o delay.o stat.o note.o env.o tone.o filter.o lfo.o modu.o vco.o wave.o out.o rd.o util.o OBJS += rec.o OBJS += cui_tone.o diff -urN midi_prog-/rec.c midi_prog/rec.c --- midi_prog-/rec.c Thu Apr 16 00:00:00 2015 +++ midi_prog/rec.c Fri Apr 17 00:00:00 2015 @@ -2,6 +2,7 @@ #include "rec.h" #define TYPE_MAX 1024 +#define BUF_MAX 1024 struct rec recs[] = { { @@ -138,6 +139,12 @@ return *(void **)memb_addr(obj, memb); } +void +memb_set_pointer(void *obj, struct memb *memb, void *p) +{ + *(void **)memb_addr(obj, memb) = p; +} + int rec_is_tail(void *obj, struct rec *rec); int @@ -257,4 +264,147 @@ fprintf(fp, "%s\n", name); rec_save(obj, rec, fp, 0); +} + +static void +non_rec_in(char *type, void *addr, FILE *fp) +{ + if(strcmp(type, "char") == 0){ + fscanf(fp, "%c", (char*)addr); + }else if(strcmp(type, "int") == 0){ + fscanf(fp, "%d", (int*)addr); + }else if(strcmp(type, "double") == 0){ + fscanf(fp, "%lf", (double*)addr); + }else{ + MSG(type); + ERR("unkown"); + } +} + +static void +skip1(int c, FILE *fp) +{ + int r = fgetc(fp); + if(r != c){ + char msg[64]; + sprintf(msg, "%c (expect %c)", r, c); + MSG(msg); + ERR("unexpect"); + } +} + +static void * +type_alloc(char *type, int n) +{ + int size = 0; + + if(type_is_rec(type)){ + struct rec *rec; + if((rec = rec_get(type)) == NULL){ + MSG(type); + ERR("not found"); + } + size = rec->size; + }else if(strcmp(type, "char")){ + size = sizeof(char); + }else if(strcmp(type, "int")){ + size = sizeof(int); + }else if(strcmp(type, "double")){ + size = sizeof(double); + }else{ + MSG(type); + ERR("unkown"); + } + return malloc(size * n); +} + +void rec_load(void *obj, struct rec *rec, FILE *fp); + +void +memb_load(void *obj, struct memb *memb, FILE *fp) +{ + char *type = memb->type; + void *addr = memb_addr(obj, memb); + void *p; + char strip_type[ TYPE_MAX ], buf[ BUF_MAX ]; + int c; + char c1; + + fscanf(fp, "%s", buf); + if(strcmp(buf, memb->name) != 0){ + MSG(buf); + MSG(memb->name); + ERR("not match memb name"); + } + + if(!type_is_pointer(type)){ + if(type_is_rec(type)){ + skip1('\n', fp); + rec_load(memb_addr(obj, memb), rec_get(memb->type), fp); + return; + } + skip1(' ', fp); + non_rec_in(type, addr, fp); + skip1('\n', fp); + return; + } + + /* type is pointer */ + + memset(strip_type, 0, sizeof(strip_type)); + memcpy(strip_type, type, strlen(type)-1); + + if(type_is_rec(strip_type)){ + struct rec *rec = rec_get(strip_type); + struct stklst *sl = NULL; + + if((c = fgetc(fp)) != '\n'){ + fscanf(fp, "%s\n", buf); + if(strcmp(buf, "NULL") != 0){ + MSG(buf); + ERR("unexpect"); + } + memb_set_pointer(obj, memb, NULL); + return; + } + + fscanf(fp, "%c", &c1); + if (c != '{') ERR("unexpect"); + skip1('\n', fp); + + for(;;){ + sl = stklst_alloc(rec->size, sl); + rec_load(sl->p, rec, fp); + if(rec_is_tail(sl->p, rec)) break; + + fscanf(fp, "%c", &c1); + if (c != ',') ERR("unexpect"); + skip1('\n', fp); + } + memb_set_pointer(obj, memb, stklst_to_arr(sl)); + + fscanf(fp, "%c", &c1); + if (c != '}') ERR("unexpect"); + skip1('\n', fp); + return; + } + + skip1(' ', fp); + if(strcmp(strip_type, "char") == 0){ + fscanf(fp, "\"%s\"", buf); + if ((p = strdup(buf)) == NULL) ERR("No Mem"); + }else{ + if ((p = type_alloc(strip_type, 1)) == NULL) ERR("No Mem"); + non_rec_in(strip_type, p, fp); + } + memb_set_pointer(obj, memb, p); + skip1('\n', fp); +} + +void +rec_load(void *obj, struct rec *rec, FILE *fp) +{ + int i; + + for(i=0; rec->membs[i].type; i++) memb_load(obj, &rec->membs[i], fp); } diff -urN midi_prog-/rec.h midi_prog/rec.h --- midi_prog-/rec.h Thu Apr 16 00:00:00 2015 +++ midi_prog/rec.h Fri Apr 17 00:00:00 2015 @@ -20,5 +20,6 @@ struct rec *rec_get(char *name); void rec_save_text(void *rec, char *name, FILE *fp); +void rec_load(void *obj, struct rec *rec, FILE *fp); #endif diff -urN midi_prog-/tone.c midi_prog/tone.c --- midi_prog-/tone.c Thu Apr 16 00:00:00 2015 +++ midi_prog/tone.c Fri Apr 17 00:00:00 2015 @@ -493,7 +493,13 @@ void tone_load_fp(FILE *fp) { + struct tone_all_rec all; + while(fgetc(fp) != '\n'); + + rec_load(&all, rec_get("struct tone_all_rec"), fp); + tone_inf = all.tone; + tones_lst = all.tones_lst; } /* EOF */ diff -urN midi_prog-/util.c midi_prog/util.c --- midi_prog-/util.c Fri Jan 24 00:00:00 2014 +++ midi_prog/util.c Fri Apr 17 00:00:00 2015 @@ -28,4 +28,55 @@ return strtol(s, NULL, 0); } +struct stklst * +stklst_alloc(int size, struct stklst *prev) +{ + struct stklst *p; + int sz = sizeof(*p) + size; + + if((p = malloc(sz)) == NULL) ERR("No Mem"); + p->size = size; + p->p = p + 1; + p->prev = prev; + return p; +} + +void +stklst_allfree(struct stklst *p) +{ + struct stklst *prev; + for(; p; p=prev){ + prev = p->prev; + free(p); + } +} + +int +stklst_allsize(struct stklst *p) +{ + int size = 0; + for(; p; p=p->prev) size += p->size; + return size; +} + +static void * +arr_set(struct stklst *p, void *arr) +{ + if(p == NULL) return arr; + arr = arr_set(p->prev, arr); + memcpy(arr, p->p, p->size); + return ((char*)arr) + p->size; +} + +void * +stklst_to_arr(struct stklst *p) +{ + void *arr; + + if((arr = malloc(stklst_allsize(p))) == NULL) ERR("No Mem"); + arr_set(p, arr); + stklst_allfree(p); + return arr; +} + /* EOF */ diff -urN midi_prog-/util.h midi_prog/util.h --- midi_prog-/util.h Fri Jan 24 00:00:00 2014 +++ midi_prog/util.h Fri Apr 17 00:00:00 2015 @@ -18,4 +18,16 @@ char *opt_str(char *key, int ac, char **av, char *def); int opt_int(char *key, int ac, char **av, int def); + +struct stklst{ + int size; + void *p; + struct stklst *prev; +}; + +struct stklst *stklst_alloc(int size, struct stklst *prev); +void stklst_allfree(struct stklst *p); +int stklst_allsize(struct stklst *p); +void *stklst_to_arr(struct stklst *p); + #endif