From 31e4c4130f6f2019127d4490407057a45f6751ae Mon Sep 17 00:00:00 2001 From: bbbradsmith Date: Mon, 22 Apr 2024 02:22:30 -0400 Subject: [PATCH] using cmd tool for testing of implemented features send errors to debug only if not logged fix debug_printf fix backwards unexpected error logic for ini settings add LOCALSETLOCALES to generate locales setting description fix missing parse error for extra junk fix channel setting names/descriptions remove group disambiguation from SET generation which now must be globally unique comment callbacks are global, mention this TEXT_COUNT needs to be the total localized strings count --- cmd/cmd.cpp | 75 +++++++++++++++++++++++++++++++++++++++-- core/core.cpp | 15 +++++---- core/enums_data.h | 76 +++++++++++++++++++++++++----------------- enums/english.txt | 11 +++--- enums/nsfplayenums.py | 73 +++++++++++++++++++++++----------------- include/nsfplaycore.h | 3 ++ include/nsfplayenums.h | 5 ++- 7 files changed, 182 insertions(+), 76 deletions(-) diff --git a/cmd/cmd.cpp b/cmd/cmd.cpp index 3389e11..0694a19 100644 --- a/cmd/cmd.cpp +++ b/cmd/cmd.cpp @@ -1,10 +1,81 @@ // stub -#include #include +#include +#include +#include + +void error_log(const char* msg) { std::fprintf(stderr,"Error: %s\n",msg); } +void debug_print(const char* msg) { std::fprintf(stdout,"Debug: %s\n",msg); } +void fatal_log(const char* msg) { std::fprintf(stderr,"Fatal: %s\n",msg); std::exit(-1); } int main() { - printf("nsfplac stub\n"); + nsfplay_set_error_log(error_log); + nsfplay_set_debug_print(debug_print); + nsfplay_set_fatal(fatal_log); + + const char* TEST_INI = + "# test comment\n" + "SAMPLERATE=12345\n" + " STEREO_ENABLE = 0 \r\n" + " error no equals\n" + "TITLE_format = a b c d \n\r" + "\tTITLE_FORMAT=\t1234\n" + "TITLE_FORMAT=1234\n" + "\tTITLE_FORMAT = 1234 \n" + "TRI_VOL = 12#34 \n" + "error bad key = 5\n" + "NSE_VOL=string # error bad int\n" + "DPCM_VOL=-3 # error range\n" + "\n" + "VOLUME=368"; + const NSFSetInit TEST_INIT[] = { + {NSFP_SET_DPCM_ON,0,NULL}, + {NSFP_SET_DPCM_ON,-2,NULL}, // out of range + {NSFP_SET_DPCM_ON,2,NULL}, // out of range + {NSFP_SET_DPCM_ON,0,"string"}, // wrong type + {NSFP_SET_TITLE_FORMAT,0,"string"}, + {NSFP_SET_TITLE_FORMAT,3,NULL}, // wrong type + {-1,0,NULL}, + }; + NSFCore* core = nsfplay_create(TEST_INI); + nsfplay_set_init(core,TEST_INIT); + nsfplay_set_key_int(core,"TRI_ON",0); + nsfplay_set_key_str(core,"TITLE_FORMAT","keyed"); + + // test info + for (int i=0;i"); + if (info.list) + { + printf("List:"); + const char* e = info.list; + for (int j=info.min_int; j<=info.max_int; ++j) + { + printf(" %d=[%s]",j,e); + e += std::strlen(e)+1; + } + printf("\n"); + } + } + + // test ini generation + for (int i=0;i 0: + parse_error(command+" has too many entries, expected: "+str(len(parse_def))) return (command,tuple(p)) # validate key references @@ -306,16 +309,12 @@ def check_setgroup(key): parse_error("SETGROUP not found: "+key) return None -def check_set(group_key,key): - for i in range(len(defs_setgroup)): - if defs_setgroup[i][0] == group_key: - for j in range(len(defs_set)): - if defs_set[j][0] == i and defs_set[j][1] == key: - return (i,j) - parser_error("SET not found in SETGROUP("+group_key+"): "+key) - return (None,None) - parse_error("SETGROUP not found: "+group_key) - return (None,None) +def check_set(key): + for i in range(len(defs_set)): + if defs_set[i][1] == key: + return i + parse_error("SET not found: "+key) + return None def check_prop(key): for i in range(len(defs_prop)): @@ -414,7 +413,7 @@ def parse_enums(path): defs_channelonlist = li elif command == "LOCAL": add_unique_entry(defs_local,1,command+" "+p[0], - [p[0],p[1],[],[],[],[],[],[],[],None,[]]) # local: key, name, list, group, set, prop, songprop, unit, channel, channelset,text + [p[0],p[1],[],[],[],[],[],[],[],None,[],(None,None)]) # local: key, name, list, group, set, prop, songprop, unit, channel, channelset, text, locales localcurrent = len(defs_local)-1 elif command == "LOCALDEFAULT": if localcurrent == None: parse_error("LOCAL must be used before "+command) @@ -437,9 +436,9 @@ def parse_enums(path): elif command == "LOCALSET": if localcurrent == None: parse_error("LOCAL must be used before "+command) else: - (gi,si) = check_set(p[0],p[1]) - if gi != None: - add_unique_entry(defs_local[localcurrent][4],2,command+" "+p[1],(gi,si,p[1],p[2])) # group, set, name, desc + si = check_set(p[0]) + if si != None: + add_unique_entry(defs_local[localcurrent][4],1,command+" "+p[1],(si,p[1],p[2])) # set, name, desc elif command == "LOCALPROP": if localcurrent == None: parse_error("LOCAL must be used before "+command) else: @@ -479,6 +478,13 @@ def parse_enums(path): if localcurrent == None: parse_error("LOCAL must be used before "+command) else: add_unique_entry(defs_local[localcurrent][10],1,command+" "+p[0],("ERROR_"+p[0],p[1])) + elif command == "LOCALSETLOCALE": + if localcurrent == None: parse_error("LOCAL must be used before "+command) + else: + if defs_local[localcurrent][11] != (None,None): + parse_error("LOCALSETLOCALE already used") + else: + defs_local[localcurrent][11] = list(p) parse_path = None def parse_enum_files(files): @@ -574,10 +580,18 @@ def generate_enums(file_enum,file_data,do_write): for l in defs_local: list_locale.append(l[0]) list_locale_index = len(defs_list) defs_list.append(list_locale) + locale_set_index = len(defs_set) defs_set.append((0,LOCALE_KEY,0,0,locs-1,list_locale_index,False)) # SETLIST: group-0, LOCALE_KEY, default, min, max, list, not-string - for i in range(len(defs_local)): # create the list names in each locale + for i in range(len(defs_local)): + # create the list names in each locale for j in range(len(defs_local)): defs_local[i][2].append((list_locale_index,j,defs_local[j][1])) # LOCALLIST: LOCALE_KEY, locale-key, locale-name + # create the set name/desc in each locale + (name,desc) = defs_local[i][11] + if name == None or desc == None: + warn("LOCAL("+defs_local[i][0]+") missing: LOCALSETLOCALE * *") + (name,desc) = ("*","*") + defs_local[i][4].append((locale_set_index,name,desc)) # map each list to a text index, and gather the locale strings to go with it gen_enum("NSFP_LIST_COUNT",len(defs_list)); table_list = [] @@ -705,9 +719,9 @@ def generate_enums(file_enum,file_data,do_write): name = None mapped = False for j in range(len(defs_local[i][8])): - if (defs_local[i][8][0] == ci): + if (defs_local[i][8][j][0] == ci): mapped = True - name = defs_local[i][8][1] + name = defs_local[i][8][j][1] if not mapped: warn("LOCAL("+defs_local[i][0]+") missing: LOCALCHANNEL "+unit_key+" "+channel_key+" *") if name == "*": name = None if name != None: names[i] = name @@ -716,7 +730,7 @@ def generate_enums(file_enum,file_data,do_write): names[j] = names[0] table_locale[i].append(gen_text(names[i])) for j in range(3): - defs_local[i][4].append((gi,si+j,names[i]+defs_local[i][9][j+0],names[i]+defs_local[i][9][j+3])) + defs_local[i][4].append((si+j,names[i]+defs_local[i][9][j+0],names[i]+defs_local[i][9][j+3])) gen_break(0); gen_line("};",1) gen_break(1) @@ -757,13 +771,13 @@ def generate_enums(file_enum,file_data,do_write): name = None desc = None mapped = False - for (lgi,lsi,lname,ldesc) in defs_local[i][4]: - if lgi == gi and lsi == si: + for (lsi,lname,ldesc) in defs_local[i][4]: + if lsi == si: mapped = True name = lname desc = ldesc break - if not mapped: warn("LOCAL("+defs_local[i][0]+") missing: LOCALSET "+group_key+" "+set_key+" * *") + if not mapped: warn("LOCAL("+defs_local[i][0]+") missing: LOCALSET "+set_key+" * *") if name == "*": name = None if desc == "*": desc = None if name != None: names[i] = name @@ -845,7 +859,6 @@ def generate_enums(file_enum,file_data,do_write): # # generate extra text # - gen_enum("NSFP_TEXT_COUNT",len(defs_local[0][10])) for ti in range(len(defs_local[0][10])): text_key = defs_local[0][10][ti][0] gen_enum("NSFP_"+text_key,len(table_locale[0])) @@ -862,7 +875,6 @@ def generate_enums(file_enum,file_data,do_write): if name == "*": name = None if name != None: names[i] = name table_locale[i].append(gen_text(names[i])) - gen_break(0) # verify there aren't stray TEXT definitions outside the default locale for i in range(1,locs): for (text_key,text_name) in defs_local[i][10]: @@ -875,6 +887,8 @@ def generate_enums(file_enum,file_data,do_write): # # generate text data tables # + gen_enum("NSFP_TEXT_COUNT",len(table_locale[0])) + gen_break(0); gen_enum("NSFP_LOCALE_COUNT",len(defs_local)) gen_line("const int32_t NSFPD_LOCAL_TEXT[NSFP_LOCALE_COUNT][%d] = {" % (len(table_locale[0])),1) for i in range(0,locs): @@ -882,7 +896,6 @@ def generate_enums(file_enum,file_data,do_write): gen_line("{",1) gen_data(table_locale[i],mode=3) gen_line("},",1) - gen_break(0); gen_line("};",1) gen_break(1); gen_line("const uint8_t NSFPD_LOCAL_TEXT_DATA[0x%06X] = {" % (len(gen_text_blob)),1) diff --git a/include/nsfplaycore.h b/include/nsfplaycore.h index bcbc625..457322e 100644 --- a/include/nsfplaycore.h +++ b/include/nsfplaycore.h @@ -49,11 +49,13 @@ const char* nsfplay_last_error(const NSFCore* core); // but multiple errors could happen in one call, // this provides a way to catch all of them. // - error msg will not end with newline. +// - global, can be set before creating a core. void nsfplay_set_error_log(void (*error_callback)(const char* msg)); // for debug builds, sets a custom debug output function for diagnostics // - default will print to stdout. // - debug msg will not end with newline. +// - global, can be set before creating a core. void nsfplay_set_debug_print(void (*debug_print_callback)(const char* msg)); // set a callback to handle a fatal error @@ -62,6 +64,7 @@ void nsfplay_set_debug_print(void (*debug_print_callback)(const char* msg)); // - If no callback is provided, or if it returns, it will print msg to stderr, // then std::exit(-1) to close the application. // - fatal msg will not end with newline. +// - global, can be set before creating a core. void nsfplay_set_fatal(void (*fatal_callback)(const char* msg)); diff --git a/include/nsfplayenums.h b/include/nsfplayenums.h index 9726bb0..cd541b8 100644 --- a/include/nsfplayenums.h +++ b/include/nsfplayenums.h @@ -1,6 +1,6 @@ #pragma once // generated by nsfplayenums.py -// 2024-04-22 00:45:03 +// 2024-04-22 02:19:01 #define NSFP_LIST_COUNT 2 #define NSFP_LIST_ENABLE 0 @@ -60,7 +60,6 @@ #define NSFP_SONGPROP_INFO 4 #define NSFP_SONGPROP_BLOB 5 -#define NSFP_TEXT_COUNT 8 #define NSFP_TEXT_TEXT 65 #define NSFP_ERROR_SET_INVALID 66 #define NSFP_ERROR_SET_TYPE 67 @@ -69,9 +68,9 @@ #define NSFP_ERROR_INI_BAD_KEY 70 #define NSFP_ERROR_INI_BAD_INT 71 #define NSFP_ERROR_INI_BAD_RANGE 72 +#define NSFP_TEXT_COUNT 73 #define NSFP_LOCALE_COUNT 2 #define NSFP_LOCALE_ENGLISH 0 #define NSFP_LOCALE_JAPANESE 1 - // end of file