# HG changeset patch # User Matti Hamalainen # Date 1578265345 -7200 # Node ID 439d08a113658437884a951f71fe2dfc3f4e0e66 # Parent 7c78ec8f6abde611b24473b2b90c2145ba23ca5e Add support for STIL database in output. The output format is probably going to change in future, and it is not very controllable particularly in the "-F" formatting mode, but at least it is there. diff -r 7c78ec8f6abd -r 439d08a11365 sidinfo.c --- a/sidinfo.c Mon Jan 06 01:01:27 2020 +0200 +++ b/sidinfo.c Mon Jan 06 01:02:25 2020 +0200 @@ -30,6 +30,9 @@ // Songlengths database filename prefix (.md5|.txt appended) #define SET_SLDB_FILEBASE "Songlengths" +// STIL database file +#define SET_STILDB_FILENAME "STIL.txt" + enum { @@ -100,6 +103,8 @@ { "Hash" , NULL , OTYPE_STR }, { "Songlengths" , "Song lengths" , OTYPE_OTHER }, + + { "STIL" , "STIL information" , OTYPE_OTHER }, }; static const int noptPSOptions = sizeof(optPSOptions) / sizeof(optPSOptions[0]); @@ -107,7 +112,8 @@ // Option variables char *setHVSCPath = NULL, - *setSLDBPath = NULL; + *setSLDBPath = NULL, + *setSTILDBPath = NULL; BOOL setSLDBNewFormat = FALSE, optParsable = FALSE, optNoNamePrefix = FALSE, @@ -121,6 +127,8 @@ PSFStack optFormat; SIDLibSLDB *sidSLDB = NULL; +SIDLibSTILDB *sidSTILDB = NULL; + BOOL setUseChConv; #ifdef HAVE_ICONV @@ -143,7 +151,8 @@ { 4, 'x', "hex", "Use hexadecimal values", OPT_NONE }, { 7, 'F', "format", "Use given format string (see below)", OPT_ARGREQ }, { 8, 'H', "hvsc", "Specify path to HVSC root directory", OPT_ARGREQ }, - { 9, 'S', "sldb", "Specify Songlengths.(txt|md5) file (use -H if possible)", OPT_ARGREQ }, + { 9, 'S', "sldb", "Specify Songlengths.(txt|md5) file", OPT_ARGREQ }, + {13, 'T', "stildb", "Specify STIL.txt file", OPT_ARGREQ }, {12, 'R', "recurse", "Recurse into sub-directories", OPT_NONE }, }; @@ -263,6 +272,24 @@ } +const char *siStripHVSCPath(const char *filename) +{ + if (setHVSCPath != NULL) + { + const char *hvsc = setHVSCPath, *fptr = filename; + + // Compare until end of string(s) + for (; *hvsc != 0 && *fptr != 0 && *hvsc == *fptr; hvsc++, fptr++); + + // Full match? + if (*hvsc == 0) + return fptr - 1; + } + + return filename; +} + + char *siCheckHVSCFilePath(const char *filebase, const char *fext) { th_stat_data sdata; @@ -791,6 +818,10 @@ th_pstr_cpy(&setSLDBPath, optArg); break; + case 13: + th_pstr_cpy(&setSTILDBPath, optArg); + break; + case 11: optEscapeChars = optArg; break; @@ -1042,6 +1073,30 @@ siPrintFieldSeparator(outFile); } break; + + case 23: + if (psid->stil != NULL) + for (int nsubtune = 0; nsubtune < psid->stil->nsubtunes; nsubtune++) + { + SIDLibSTILSubTune *node = psid->stil->subtunes[nsubtune]; + if (node != NULL) + { + for (int nfield = 0; nfield < STF_LAST; nfield++) + for (int nitem = 0; nitem < node->fields[nfield].ndata; nitem++) + { + snprintf(tmp, sizeof(tmp), "STIL/%s/%d", + sidlib_stil_fields[nfield], nitem + 1); + + siPrintFieldPrefixName(outFile, tmp); + siPrintPSIDInfoLine(outFile, shown, + siGetInfoFormat(item, OTYPE_STR), + OTYPE_STR, + node->fields[nfield].data[nitem], + -1, TRUE); + } + } + } + break; } } @@ -1053,6 +1108,13 @@ } +void siSTILError(th_ioctx *fh, const int err, const char *msg) +{ + (void) err; + THERR("[%s:%d] %s\n", fh->filename, fh->line, msg); +} + + BOOL siHandleSIDFile(const char *filename) { SIDLibPSIDHeader *psid = NULL; @@ -1080,6 +1142,14 @@ if (sidSLDB != NULL) psid->lengths = sidlib_sldb_get_by_hash(sidSLDB, psid->hash); + // Get STIL information, if any + if (sidSTILDB != NULL) + { + psid->stil = sidlib_stildb_get_node(sidSTILDB, siStripHVSCPath(filename)); + if (psid->stil != NULL) + psid->stil->lengths = psid->lengths; + } + // Output for (int index = 0; index < optFormat.nitems; index++) { @@ -1303,6 +1373,9 @@ if (setSLDBPath == NULL) setSLDBPath = siCheckHVSCFilePath(SET_SLDB_FILEBASE, ".txt"); + + if (setSTILDBPath == NULL) + setSTILDBPath = siCheckHVSCFilePath(SET_STILDB_FILENAME, NULL); } if (setSLDBPath != NULL) @@ -1319,6 +1392,8 @@ goto err1; } + th_io_set_handlers(inFile, siSTILError, NULL); + THMSG(1, "Reading SLDB (%s format [%s]): %s\n", setSLDBNewFormat ? "new" : "old", setSLDBNewFormat ? ".md5" : ".txt", @@ -1350,6 +1425,49 @@ inFile = NULL; } + if (setSTILDBPath != NULL) + { + // Initialize STILDB + int ret = THERR_OK; + + if ((ret = th_io_fopen(&inFile, &th_stdio_io_ops, setSTILDBPath, "r")) != THERR_OK) + { + THERR("Could not open STIL database '%s': %s\n", + setSTILDBPath, th_error_str(ret)); + goto err2; + } + + th_io_set_handlers(inFile, siSTILError, NULL); + + THMSG(1, "Reading STIL database: %s\n", + setSTILDBPath); + + if ((ret = sidlib_stildb_new(&sidSTILDB)) != THERR_OK) + { + THERR("Could not allocate STIL database structure: %s\n", + th_error_str(ret)); + goto err2; + } + + if ((ret = sidlib_stildb_read(inFile, sidSTILDB)) != THERR_OK) + { + THERR("Error parsing STIL: %s\n", + th_error_str(ret)); + goto err2; + } + + if ((ret = sidlib_stildb_build_index(sidSTILDB)) != THERR_OK) + { + THERR("Error building STIL index: %s.\n", + th_error_str(ret)); + goto err2; + } + +err2: + th_io_free(inFile); + inFile = NULL; + } + // Process files if (!th_args_process(argc, argv, optList, optListN, NULL, argHandleFile, OPTH_ONLY_OTHER)) @@ -1370,6 +1488,10 @@ siClearStack(&optFormat); th_free(setHVSCPath); th_free(setSLDBPath); + th_free(setSTILDBPath); + sidlib_sldb_free(sidSLDB); + sidlib_stildb_free(sidSTILDB); + return 0; } diff -r 7c78ec8f6abd -r 439d08a11365 sidlib.h --- a/sidlib.h Mon Jan 06 01:01:27 2020 +0200 +++ b/sidlib.h Mon Jan 06 01:02:25 2020 +0200 @@ -101,6 +101,8 @@ char *filename; int nsubtunes; SIDLibSTILSubTune **subtunes; + + SIDLibSLDBNode *lengths; } SIDLibSTILNode; @@ -138,6 +140,7 @@ th_md5hash_t hash; // Songlength database hash SIDLibSLDBNode *lengths; // Songlength information node pointer + SIDLibSTILNode *stil; // STIL database node pointer BOOL allocated; // TRUE if structure has been allocated } SIDLibPSIDHeader;