changeset 89:d9cb7c635e7b

Implement initial SLDB support.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 12 Feb 2016 01:17:52 +0200
parents c5ff71d64e53
children 2ab9ab4b59eb
files sidinfo.c
diffstat 1 files changed, 92 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/sidinfo.c	Fri Feb 12 01:13:48 2016 +0200
+++ b/sidinfo.c	Fri Feb 12 01:17:52 2016 +0200
@@ -5,10 +5,12 @@
  */
 #include "th_args.h"
 #include "th_string.h"
+#include "th_file.h"
 #include "sidlib.h"
 
 
 // Some constants
+#define SET_SLDB_FILENAME "Songlengths.txt"
 
 
 // Flags for various information fields
@@ -32,6 +34,7 @@
     SIF_PLAYSID_TUNE   = 0x00002000,
     SIF_VIDEO_CLOCK    = 0x00004000,
     SIF_SID_MODEL      = 0x00008000,
+    SIF_SONGLENGTHS    = 0x00010000,
 
     SIF_DATA_SIZE      = 0x00100000,
     SIF_HASH           = 0x00200000,
@@ -86,6 +89,8 @@
     { SIF_SID_COPYRIGHT  , "Copyright"  , NULL },
     { SIF_HASH           , "Hash"       , NULL },
 
+    { SIF_SONGLENGTHS    , "Songlengths", "Song lengths" },
+
     { SIF_ALL            , "All"        , NULL },
 };
 
@@ -93,6 +98,8 @@
 
 
 // Option variables
+char   *setHVSCPath = NULL,
+       *setSLDBPath = NULL;
 BOOL	optParsable = FALSE,
         optNoNamePrefix = FALSE,
         optHexadecimal = FALSE,
@@ -103,6 +110,8 @@
 
 PSFStack optFormat;
 
+SIDLibSLDB *sidSLDB = NULL;
+
 
 // Define option arguments
 static const th_optarg_t optList[] =
@@ -115,6 +124,8 @@
     { 3, 'f', "fields",     "Show only specified field(s)", OPT_ARGREQ },
     { 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 documents directory", OPT_ARGREQ },
+    { 9, 'S', "sldb",       "Specify Songlengths.txt file (use -H if possible)", OPT_ARGREQ },
 };
 
 static const int optListN = sizeof(optList) / sizeof(optList[0]);
@@ -148,6 +159,9 @@
         "Format strings for '-F' option are composed of @fields@ that\n"
         "are expanded to their value. Also, escape sequences \\r, \\n and \\t\n"
         "can be used: -F \"hash=@hash@\\ncopy=@copyright@\\n\"\n"
+        "\n"
+        "When specifying HVSC path, it is preferable to use -H/--hvsc option,\n"
+        "as STIL.txt and Songlengths.txt will be automatically used from there.\n"
         , th_prog_name);
 }
 
@@ -380,6 +394,14 @@
             return FALSE;
         break;
 
+    case 8:
+        setHVSCPath = th_strdup(optArg);
+        break;
+
+    case 9:
+        setSLDBPath = th_strdup(optArg);
+        break;
+
     default:
         THERR("Unknown option '%s'.\n", currArg);
         return FALSE;
@@ -410,8 +432,9 @@
 }
 
 
-static void siPrintFieldPrefix(FILE *outFile, const char *name)
+static void siPrintFieldPrefix(FILE *outFile, const PSFOption *opt)
 {
+    const char *name = (optParsable || opt->lname == NULL) ? opt->name : opt->lname;
     if (!optNoNamePrefix && !optFormat.nitems)
         fprintf(outFile, optParsable ? "%s=" : "%-20s : ", name);
 }
@@ -432,7 +455,7 @@
         va_list ap;
         const char *fmt = optHexadecimal ? (xaltfmt != NULL ? xaltfmt : xfmt) : xfmt;
 
-        siPrintFieldPrefix(outFile, (optParsable || opt->lname == NULL) ? opt->name : opt->lname);
+        siPrintFieldPrefix(outFile, opt);
 
         va_start(ap, xaltfmt);
         vfprintf(outFile, fmt, ap);
@@ -443,6 +466,7 @@
     }
 }
 
+
 #define PR(xfmt, xaltfmt, ...) siPrintPSIDInfoLine(outFile, shown, xindex, xfmt, xaltfmt, __VA_ARGS__ )
 
 
@@ -483,12 +507,34 @@
                 const PSFOption *opt = &optPSFlags[xindex];
                 if (optFormat.nitems || (optFields & opt->flag))
                 {
-                    siPrintFieldPrefix(outFile, "Hash");
+                    siPrintFieldPrefix(outFile, opt);
                     th_md5_print(outFile, psid->hash);
                     siPrintFieldSeparator(outFile);
                 }
             }
             break;
+
+        case 18:
+            {
+                const PSFOption *opt = &optPSFlags[xindex];
+                if (optFormat.nitems || (optFields & opt->flag))
+                {
+                    siPrintFieldPrefix(outFile, opt);
+                    if (psid->lengths != NULL)
+                    {
+                        int i;
+                        for (i = 0; i < psid->lengths->nlengths; i++)
+                        {
+                            int len = psid->lengths->lengths[i];
+                            fprintf(outFile, "%d:%d%s", len / 60, len % 60,
+                                (i < psid->lengths->nlengths - 1) ? " " : "");
+                        }
+                    }
+                    siPrintFieldSeparator(outFile);
+                }
+            }
+            break;
+
     }
 }
 
@@ -517,6 +563,10 @@
         goto error;
     }
 
+    // Get songlength information, if any
+    if (sidSLDB != NULL)
+        psid.lengths = si_sldb_get_by_hash(sidSLDB, psid.hash);
+
     // Output
     if (optFormat.nitems)
     {
@@ -575,10 +625,42 @@
         optNoNamePrefix = TRUE;
     }
 
+    if (setHVSCPath != NULL)
+    {
+        if (setSLDBPath == NULL)
+            setSLDBPath = th_strdup_printf("%s%c%s", setHVSCPath, TH_DIR_SEPARATOR, SET_SLDB_FILENAME);
+    }
+
+    if (setSLDBPath != NULL)
+    {
+        // Initialize SLDB
+        int ret;
+        th_ioctx *ctx = th_io_new(&th_stdio_io_ops);
+        if (ctx == NULL || th_io_open(ctx, setSLDBPath, "r") != THERR_OK)
+        {
+            THERR("Ululu!\n");
+            goto out;
+        }
+
+        if ((sidSLDB = si_sldb_new()) == NULL ||
+            si_sldb_read(ctx, sidSLDB) != THERR_OK)
+        {
+            THERR("Error parsing SLDB.\n");
+            goto out;
+        }
+
+        if ((ret = si_sldb_build_index(sidSLDB)) != THERR_OK)
+        {
+            THERR("Error building SLDB index: %s.\n",
+                th_error_str(ret));
+            goto out;
+        }
+    }
+
     // Process files
     if (!th_args_process(argc, argv, optList, optListN,
         argHandleOpt, argHandleFile, OPTH_ONLY_OTHER))
-        return -2;
+        goto out;
 
     if (optNFiles == 0)
     {
@@ -586,5 +668,11 @@
         THERR("No filename(s) specified.\n");
     }
 
+out:
+
+    th_free(setHVSCPath);
+    th_free(setSLDBPath);
+    th_free(setSTILPath);
+    si_sldb_free(sidSLDB);
     return 0;
 }