# HG changeset patch # User Matti Hamalainen # Date 1455525322 -7200 # Node ID 59b5b99f4280e2c997dd239cca06322bde53dfdb # Parent d621e8b59a1ce0098c04bc7cd7f19008d0dc2a48 Reimplement '-f' option differently. diff -r d621e8b59a1c -r 59b5b99f4280 sidinfo.c --- 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)