changeset 109:59b5b99f4280

Reimplement '-f' option differently.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 15 Feb 2016 10:35:22 +0200
parents d621e8b59a1c
children e9dbedc4d5e4
files sidinfo.c
diffstat 1 files changed, 118 insertions(+), 151 deletions(-) [+]
line wrap: on
line diff
--- a/sidinfo.c	Mon Feb 15 09:22:18 2016 +0200
+++ b/sidinfo.c	Mon Feb 15 10:35:22 2016 +0200
@@ -13,42 +13,12 @@
 #define SET_SLDB_FILENAME "Songlengths.txt"
 
 
-// Flags for various information fields
-enum
-{
-    SIF_NONE           = 0,
-
-    SIF_TYPE           = 0x00000001,
-    SIF_VERSION        = 0x00000002,
-    SIF_DATA_OFFS      = 0x00000004,
-    SIF_LOAD_ADDR      = 0x00000008,
-    SIF_INIT_ADDR      = 0x00000010,
-    SIF_PLAY_ADDR      = 0x00000020,
-    SIF_SONGS          = 0x00000040,
-    SIF_START_SONG     = 0x00000080,
-    SIF_SPEEDS         = 0x00000100,
-    SIF_SID_NAME       = 0x00000200,
-    SIF_SID_AUTHOR     = 0x00000400,
-    SIF_SID_COPYRIGHT  = 0x00000800,
-    SIF_PLAYER_TYPE    = 0x00001000,
-    SIF_PLAYSID_TUNE   = 0x00002000,
-    SIF_VIDEO_CLOCK    = 0x00004000,
-    SIF_SID_MODEL      = 0x00008000,
-    SIF_SONGLENGTHS    = 0x00010000,
-
-    SIF_DATA_SIZE      = 0x00100000,
-    SIF_HASH           = 0x00200000,
-    SIF_FILENAME       = 0x01000000,
-
-    SIF_ALL            = 0x0fffffff,
-};
-
-
 typedef struct
 {
     int cmd;
     char *str;
     char chr;
+    int flags;
 } PSFStackItem;
 
 
@@ -61,40 +31,37 @@
 
 typedef struct
 {
-    uint32_t flag;
     char *name;
     char *lname;
 } PSFOption;
 
 
-static const PSFOption optPSFlags[] =
+static const PSFOption optPSOptions[] =
 {
-    { SIF_FILENAME       , "Filename"     , NULL },
-    { SIF_TYPE           , "Type"         , NULL },
-    { SIF_VERSION        , "Version"      , NULL },
-    { SIF_PLAYER_TYPE    , "PlayerType"   , "Player type" },
-    { SIF_PLAYSID_TUNE   , "PlayerCompat" , "Player compatibility" },
-    { SIF_VIDEO_CLOCK    , "VideoClock"   , "Video clock speed" },
-    { SIF_SID_MODEL      , "SIDModel"     , "SID model" },
+    { "Filename"     , NULL },
+    { "Type"         , NULL },
+    { "Version"      , NULL },
+    { "PlayerType"   , "Player type" },
+    { "PlayerCompat" , "Player compatibility" },
+    { "VideoClock"   , "Video clock speed" },
+    { "SIDModel"     , "SID model" },
 
-    { SIF_DATA_OFFS      , "DataOffs"     , "Data offset" },
-    { SIF_DATA_SIZE      , "DataSize"     , "Data size" },
-    { SIF_LOAD_ADDR      , "LoadAddr"     , "Load address" },
-    { SIF_INIT_ADDR      , "InitAddr"     , "Init address" },
-    { SIF_PLAY_ADDR      , "PlayAddr"     , "Play address" },
-    { SIF_SONGS          , "Songs"        , "Songs" },
-    { SIF_START_SONG     , "StartSong"    , "Start song" },
-    { SIF_SID_NAME       , "Name"         , NULL },
-    { SIF_SID_AUTHOR     , "Author"       , NULL },
-    { SIF_SID_COPYRIGHT  , "Copyright"    , NULL },
-    { SIF_HASH           , "Hash"         , NULL },
+    { "DataOffs"     , "Data offset" },
+    { "DataSize"     , "Data size" },
+    { "LoadAddr"     , "Load address" },
+    { "InitAddr"     , "Init address" },
+    { "PlayAddr"     , "Play address" },
+    { "Songs"        , "Songs" },
+    { "StartSong"    , "Start song" },
+    { "Name"         , NULL },
+    { "Author"       , NULL },
+    { "Copyright"    , NULL },
+    { "Hash"         , NULL },
 
-    { SIF_SONGLENGTHS    , "Songlengths"  , "Song lengths" },
-
-    { SIF_ALL            , "All"          , NULL },
+    { "Songlengths"  , "Song lengths" },
 };
 
-static const int noptPSFlags = sizeof(optPSFlags) / sizeof(optPSFlags[0]);
+static const int noptPSOptions = sizeof(optPSOptions) / sizeof(optPSOptions[0]);
 
 
 // Option variables
@@ -103,9 +70,9 @@
 BOOL	optParsable = FALSE,
         optNoNamePrefix = FALSE,
         optHexadecimal = FALSE,
-        optOneLine = FALSE;
+        optOneLine = FALSE,
+        optNormal = TRUE;
 char    *optFieldSep = NULL;
-uint32_t optFields = SIF_ALL;
 int     optNFiles = 0;
 
 PSFStack optFormat;
@@ -141,16 +108,16 @@
         "\n"
         "Available fields:\n");
 
-    for (len = index = 0; index < noptPSFlags; index++)
+    for (len = index = 0; index < noptPSOptions; index++)
     {
-        const PSFOption *opt = &optPSFlags[index];
+        const PSFOption *opt = &optPSOptions[index];
         len += strlen(opt->name) + 3;
         if (len >= 72)
         {
             printf("\n");
             len = 0;
         }
-        printf("%s%s", opt->name, (index < noptPSFlags - 1) ? ", " : "\n\n");
+        printf("%s%s", opt->name, (index < noptPSOptions - 1) ? ", " : "\n\n");
     }
 
     printf(
@@ -169,9 +136,9 @@
 int argMatchPSField(const char *field)
 {
     int index, found = -1;
-    for (index = 0; index < noptPSFlags; index++)
+    for (index = 0; index < noptPSOptions; index++)
     {
-        const PSFOption *opt = &optPSFlags[index];
+        const PSFOption *opt = &optPSOptions[index];
         if (th_strcasecmp(opt->name, field) == 0)
         {
             if (found >= 0)
@@ -201,25 +168,6 @@
 }
 
 
-BOOL argParsePSField(char *opt, char *end, uint32_t *fields)
-{
-    // Trim whitespace
-    if (end != NULL)
-        while (end > opt && *end && th_isspace(*end)) end--;
-
-    while (*opt && th_isspace(*opt)) opt++;
-
-    // Match field name
-    char *field = (end != NULL) ? th_strndup(opt, end - opt) : th_strdup(opt);
-    int found = argMatchPSFieldError(field);
-    if (found >= 0)
-        *fields |= optPSFlags[found].flag;
-
-    th_free(field);
-    return FALSE;
-}
-
-
 BOOL siStackAddItem(PSFStack *stack, const PSFStackItem *item)
 {
     if (stack->items == NULL || stack->nitems + 1 >= stack->nallocated)
@@ -257,6 +205,40 @@
 }
 
 
+BOOL argParsePSFields(PSFStack *stack, const char *fmt)
+{
+    const char *start = fmt;
+    siClearStack(stack);
+
+    while (*start)
+    {
+        PSFStackItem item;
+        const char *end = strchr(start, ',');
+        char *field = (end != NULL) ?
+            th_strndup_trim(start, end - start - 1, TH_TRIM_BOTH) :
+            th_strdup_trim(start, TH_TRIM_BOTH);
+
+        int found = argMatchPSFieldError(field);
+        th_free(field);
+
+        if (found < 0)
+            return FALSE;
+
+        item.cmd = found;
+        item.str = NULL;
+        if (!siStackAddItem(stack, &item))
+            return FALSE;
+
+        if (!end)
+            break;
+
+        start = end + 1;
+    }
+
+    return TRUE;
+}
+
+
 //
 // Parse a format string into a PSFStack structure
 //
@@ -298,7 +280,7 @@
                 }
                 else
                 {
-                    char *field = th_strndup(start, fmt - start);
+                    char *field = th_strndup_trim(start, fmt - start, TH_TRIM_BOTH);
                     int ret = argMatchPSFieldError(field);
                     if (ret >= 0)
                     {
@@ -357,23 +339,8 @@
         break;
 
     case 3:
-        {
-            char *start = optArg;
-            optFields = SIF_NONE;
-
-            while (*start)
-            {
-                char *end = strchr(start, ',');
-
-                if (!argParsePSField(start, end, &optFields))
-                    return FALSE;
-
-                if (!end)
-                    break;
-
-                start = end + 1;
-            }
-        }
+        if (!argParsePSFields(&optFormat, optArg))
+            return FALSE;
         break;
 
     case 4:
@@ -390,6 +357,7 @@
         break;
 
     case 7:
+        optNormal = FALSE;
         if (!argParsePSFormatStr(&optFormat, optArg))
             return FALSE;
         break;
@@ -435,35 +403,32 @@
 static void siPrintFieldPrefix(FILE *outFile, const PSFOption *opt)
 {
     const char *name = (optParsable || opt->lname == NULL) ? opt->name : opt->lname;
-    if (!optNoNamePrefix && !optFormat.nitems)
+    if (!optNoNamePrefix && optNormal)
         fprintf(outFile, optParsable ? "%s=" : "%-20s : ", name);
 }
 
 
 static void siPrintFieldSeparator(FILE *outFile)
 {
-    if (!optFormat.nitems)
+    if (optNormal)
         fputs(optOneLine ? optFieldSep : "\n", outFile);
 }
 
 
 static void siPrintPSIDInfoLine(FILE *outFile, BOOL *shown, const int xindex, const char *xfmt, const char *xaltfmt, ...)
 {
-    const PSFOption *opt = &optPSFlags[xindex];
-    if (optFormat.nitems || (optFields & opt->flag))
-    {
-        va_list ap;
-        const char *fmt = optHexadecimal ? (xaltfmt != NULL ? xaltfmt : xfmt) : xfmt;
+    const PSFOption *opt = &optPSOptions[xindex];
+    va_list ap;
+    const char *fmt = optHexadecimal ? (xaltfmt != NULL ? xaltfmt : xfmt) : xfmt;
 
-        siPrintFieldPrefix(outFile, opt);
+    siPrintFieldPrefix(outFile, opt);
 
-        va_start(ap, xaltfmt);
-        vfprintf(outFile, fmt, ap);
-        va_end(ap);
+    va_start(ap, xaltfmt);
+    vfprintf(outFile, fmt, ap);
+    va_end(ap);
 
-        siPrintFieldSeparator(outFile);
-        *shown = TRUE;
-    }
+    siPrintFieldSeparator(outFile);
+    *shown = TRUE;
 }
 
 
@@ -504,34 +469,28 @@
 
         case 17:
             {
-                const PSFOption *opt = &optPSFlags[xindex];
-                if (optFormat.nitems || (optFields & opt->flag))
-                {
-                    siPrintFieldPrefix(outFile, opt);
-                    th_md5_print(outFile, psid->hash);
-                    siPrintFieldSeparator(outFile);
-                }
+                const PSFOption *opt = &optPSOptions[xindex];
+                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))
+                const PSFOption *opt = &optPSOptions[xindex];
+                siPrintFieldPrefix(outFile, opt);
+                if (psid->lengths != NULL)
                 {
-                    siPrintFieldPrefix(outFile, opt);
-                    if (psid->lengths != NULL)
+                    int i;
+                    for (i = 0; i < psid->lengths->nlengths; i++)
                     {
-                        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) ? " " : "");
-                        }
+                        int len = psid->lengths->lengths[i];
+                        fprintf(outFile, "%d:%d%s", len / 60, len % 60,
+                            (i < psid->lengths->nlengths - 1) ? " " : "");
                     }
-                    siPrintFieldSeparator(outFile);
                 }
+                siPrintFieldSeparator(outFile);
             }
             break;
 
@@ -568,32 +527,27 @@
         psid.lengths = si_sldb_get_by_hash(sidSLDB, psid.hash);
 
     // Output
-    if (optFormat.nitems)
+    for (index = 0; index < optFormat.nitems; index++)
     {
-        for (index = 0; index < optFormat.nitems; index++)
+        PSFStackItem *item = &optFormat.items[index];
+        switch (item->cmd)
         {
-            PSFStackItem *item = &optFormat.items[index];
-            switch (item->cmd)
-            {
-                case -1:
-                    siPrintStrEscapes(outFile, item->str);
-                    break;
+            case -1:
+                siPrintStrEscapes(outFile, item->str);
+                break;
 
-                case -2:
-                    fputc(item->chr, outFile);
-                    break;
+            case -2:
+                fputc(item->chr, outFile);
+                break;
 
-                default:
-                    siPrintPSIDInformationField(outFile, filename, &psid, &shown, item->cmd);
-                    break;
-            }
+            default:
+                siPrintPSIDInformationField(outFile, filename, &psid, &shown, item->cmd);
+                break;
         }
     }
-    else
+    
+    if (optNormal)
     {
-        for (index = 0; index < noptPSFlags - 1; index++)
-            siPrintPSIDInformationField(outFile, filename, &psid, &shown, index);
-
         if (shown && optOneLine)
             fprintf(outFile, "\n");
     }
@@ -624,6 +578,19 @@
         optParsable = FALSE;
         optNoNamePrefix = TRUE;
     }
+    
+    if (optNormal && !optFormat.nitems)
+    {
+        int i;
+        siClearStack(&optFormat);
+        for (i = 0; i < noptPSOptions; i++)
+        {
+            PSFStackItem item;
+            item.cmd = i;
+            item.str = NULL;
+            siStackAddItem(&optFormat, &item);
+        }
+    }
 
     // Check paths
     if (setHVSCPath != NULL)