changeset 271:439d08a11365

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.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 06 Jan 2020 01:02:25 +0200
parents 7c78ec8f6abd
children 763623493f59
files sidinfo.c sidlib.h
diffstat 2 files changed, 127 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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;
 }
--- 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;