comparison sidinfo.c @ 281:514d861516b0

Further work on the STIL fields output format. It's not perfect, nor controllable, but I believe it is better now. Some further formatting control of multi-field and sub-tune STIL information is available now via -l and -n options when -F format string is being used.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 08 Jan 2020 01:37:49 +0200
parents 08695f046565
children a00d11de7a71
comparison
equal deleted inserted replaced
280:08695f046565 281:514d861516b0
118 char *setHVSCPath = NULL, 118 char *setHVSCPath = NULL,
119 *setSLDBPath = NULL, 119 *setSLDBPath = NULL,
120 *setSTILDBPath = NULL; 120 *setSTILDBPath = NULL;
121 BOOL setSLDBNewFormat = FALSE, 121 BOOL setSLDBNewFormat = FALSE,
122 optParsable = FALSE, 122 optParsable = FALSE,
123 optNoNamePrefix = FALSE, 123 optFieldNamePrefix = TRUE,
124 optHexadecimal = FALSE, 124 optHexadecimal = FALSE,
125 optFieldOutput = TRUE, 125 optFieldOutput = TRUE,
126 optRecurseDirs = FALSE; 126 optRecurseDirs = FALSE;
127 char *optOneLineFieldSep = NULL, 127 char *optOneLineFieldSep = NULL,
128 *optEscapeChars = NULL; 128 *optEscapeChars = NULL;
865 case 4: 865 case 4:
866 optHexadecimal = TRUE; 866 optHexadecimal = TRUE;
867 break; 867 break;
868 868
869 case 5: 869 case 5:
870 optNoNamePrefix = TRUE; 870 optFieldNamePrefix = FALSE;
871 break; 871 break;
872 872
873 case 6: 873 case 6:
874 optOneLineFieldSep = optArg; 874 optOneLineFieldSep = optArg;
875 break; 875 break;
965 str++; 965 str++;
966 } 966 }
967 } 967 }
968 968
969 969
970 static void siPrintFieldPrefixName(FILE *outFile, const char *name) 970 static void siPrintFieldPrefixName(FILE *outFile, const char *name, const BOOL multifield)
971 { 971 {
972 if (!optNoNamePrefix && optFieldOutput) 972 if (optFieldNamePrefix)
973 fprintf(outFile, optParsable ? "%s=" : "%-20s : ", name); 973 {
974 if (optFieldOutput && optOneLineFieldSep == NULL)
975 fprintf(outFile, optParsable ? "%s=" : "%-20s : ", name);
976 else
977 if (multifield)
978 fprintf(outFile, "[%s] ", name);
979 }
974 } 980 }
975 981
976 982
977 static void siPrintFieldPrefix(FILE *outFile, const PSFOption *opt) 983 static void siPrintFieldPrefix(FILE *outFile, const PSFOption *opt)
978 { 984 {
979 siPrintFieldPrefixName(outFile, 985 siPrintFieldPrefixName(outFile,
980 (optParsable || opt->lname == NULL) ? opt->name : opt->lname); 986 (optParsable || opt->lname == NULL) ? opt->name : opt->lname,
981 } 987 FALSE);
982 988 }
983 989
984 static void siPrintFieldSeparator(FILE *outFile) 990
991 static void siPrintFieldSeparator(FILE *outFile, const BOOL multifield)
985 { 992 {
986 if (optFieldOutput) 993 if (optFieldOutput)
987 fputs(optOneLineFieldSep != NULL ? optOneLineFieldSep : "\n", outFile); 994 fputs(optOneLineFieldSep != NULL ? optOneLineFieldSep : "\n", outFile);
995 else
996 if (multifield)
997 fputs(optOneLineFieldSep != NULL ? optOneLineFieldSep : ", ", outFile);
988 } 998 }
989 999
990 1000
991 static const char *siGetInfoFormat(const PSFStackItem *item, const int otype) 1001 static const char *siGetInfoFormat(const PSFStackItem *item, const int otype)
992 { 1002 {
1037 1047
1038 1048
1039 #define PRS(d_str, d_conv) do { \ 1049 #define PRS(d_str, d_conv) do { \
1040 siPrintFieldPrefix(outFile, opt); \ 1050 siPrintFieldPrefix(outFile, opt); \
1041 siPrintPSIDInfoLine(outFile, shown, siGetInfoFormat(item, opt->type), opt->type, d_str, -1, d_conv); \ 1051 siPrintPSIDInfoLine(outFile, shown, siGetInfoFormat(item, opt->type), opt->type, d_str, -1, d_conv); \
1042 siPrintFieldSeparator(outFile); \ 1052 siPrintFieldSeparator(outFile, FALSE); \
1043 } while (0) 1053 } while (0)
1044 1054
1045 #define PRI(d_int) do { \ 1055 #define PRI(d_int) do { \
1046 siPrintFieldPrefix(outFile, opt); \ 1056 siPrintFieldPrefix(outFile, opt); \
1047 siPrintPSIDInfoLine(outFile, shown, siGetInfoFormat(item, opt->type), opt->type, NULL, d_int, FALSE); \ 1057 siPrintPSIDInfoLine(outFile, shown, siGetInfoFormat(item, opt->type), opt->type, NULL, d_int, FALSE); \
1048 siPrintFieldSeparator(outFile); \ 1058 siPrintFieldSeparator(outFile, FALSE); \
1049 } while (0) 1059 } while (0)
1050 1060
1051 1061
1052 static void siPrintPSIDInformationField(FILE *outFile, const char *filename, 1062 static void siPrintPSIDInformationField(FILE *outFile, const char *filename,
1053 const SIDLibPSIDHeader *psid, BOOL *shown, const PSFStackItem *item) 1063 const SIDLibPSIDHeader *psid, BOOL *shown, const PSFStackItem *item)
1146 siGetInfoFormat(item, OTYPE_STR), 1156 siGetInfoFormat(item, OTYPE_STR),
1147 OTYPE_STR, 1157 OTYPE_STR,
1148 tmp, 1158 tmp,
1149 -1, FALSE); 1159 -1, FALSE);
1150 } 1160 }
1151 siPrintFieldSeparator(outFile); 1161 siPrintFieldSeparator(outFile, FALSE);
1152 } 1162 }
1153 break; 1163 break;
1154 1164
1155 case 23: 1165 case 23:
1156 if (psid->stil != NULL) 1166 if (psid->stil != NULL)
1157 for (int nsubtune = 0; nsubtune < psid->stil->nsubtunes; nsubtune++) 1167 for (int nsubtune = 0; nsubtune < psid->stil->nsubtunes; nsubtune++)
1158 { 1168 {
1159 SIDLibSTILSubTune *node = psid->stil->subtunes[nsubtune]; 1169 SIDLibSTILSubTune *node = psid->stil->subtunes[nsubtune];
1160 if (node != NULL) 1170 if (node != NULL)
1161 { 1171 {
1172 int maxdata = 0;
1162 for (int nfield = 0; nfield < STF_LAST; nfield++) 1173 for (int nfield = 0; nfield < STF_LAST; nfield++)
1163 for (int nitem = 0; nitem < node->fields[nfield].ndata; nitem++)
1164 { 1174 {
1165 if (nsubtune > 0) 1175 SIDLibSTILField *fld = &node->fields[nfield];
1176 if (fld->ndata > maxdata)
1177 maxdata = fld->ndata;
1178 }
1179
1180 for (int nitem = 0; nitem < maxdata; nitem++)
1181 for (int nfield = 0; nfield < STF_LAST; nfield++)
1182 {
1183 SIDLibSTILField *fld = &node->fields[nfield];
1184 if (nitem < fld->ndata)
1166 { 1185 {
1167 snprintf(tmp, sizeof(tmp), "STIL#%d/%s", 1186 if (nsubtune > 0)
1168 nsubtune, sidlib_stil_fields[nfield]); 1187 {
1188 snprintf(tmp, sizeof(tmp), "STIL#%d/%s",
1189 nsubtune, sidlib_stil_fields[nfield]);
1190 }
1191 else
1192 {
1193 snprintf(tmp, sizeof(tmp), "STIL/%s",
1194 sidlib_stil_fields[nfield]);
1195 }
1196
1197 siPrintFieldPrefixName(outFile, tmp, TRUE);
1198 siPrintPSIDInfoLine(outFile, shown,
1199 siGetInfoFormat(item, OTYPE_STR),
1200 OTYPE_STR,
1201 fld->data[nitem],
1202 -1, TRUE);
1203 siPrintFieldSeparator(outFile, TRUE);
1169 } 1204 }
1170 else
1171 {
1172 snprintf(tmp, sizeof(tmp), "STIL/%s",
1173 sidlib_stil_fields[nfield]);
1174 }
1175
1176 siPrintFieldPrefixName(outFile, tmp);
1177 siPrintPSIDInfoLine(outFile, shown,
1178 siGetInfoFormat(item, OTYPE_STR),
1179 OTYPE_STR,
1180 node->fields[nfield].data[nitem],
1181 -1, TRUE);
1182 siPrintFieldSeparator(outFile);
1183 } 1205 }
1184 } 1206 }
1185 } 1207 }
1186 break; 1208 break;
1187 } 1209 }
1440 THMSG(2, "Requested output LANG='%s', use charset conversion=%s\n", 1462 THMSG(2, "Requested output LANG='%s', use charset conversion=%s\n",
1441 setLang, setUseOutConv ? "yes" : "no"); 1463 setLang, setUseOutConv ? "yes" : "no");
1442 1464
1443 if (optOneLineFieldSep != NULL) 1465 if (optOneLineFieldSep != NULL)
1444 { 1466 {
1445 // For one-line format, disable parsing and prefixes 1467 // For one-line format, disable parsable and prefixes
1446 optParsable = FALSE; 1468 optParsable = FALSE;
1447 optNoNamePrefix = TRUE;
1448 1469
1449 // If no escape chars have been set, use the field separator(s) 1470 // If no escape chars have been set, use the field separator(s)
1450 if (optEscapeChars == NULL) 1471 if (optEscapeChars == NULL)
1451 optEscapeChars = optOneLineFieldSep; 1472 optEscapeChars = optOneLineFieldSep;
1452 } 1473 }