Mercurial > hg > sidinfo
comparison sidinfo.c @ 268:6312d33d1361
Refactor and improve the field formatting / printing to be more flexible.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 06 Jan 2020 00:59:35 +0200 |
parents | ac6b5957b82b |
children | cea4a7df9efd |
comparison
equal
deleted
inserted
replaced
267:ac6b5957b82b | 268:6312d33d1361 |
---|---|
430 return th_vprintf_put_int_format(ctx, vputch, buf, f_flags, f_width, f_prec, f_len, vret, f_neg, f_unsig, f_alt); | 430 return th_vprintf_put_int_format(ctx, vputch, buf, f_flags, f_width, f_prec, f_len, vret, f_neg, f_unsig, f_alt); |
431 } | 431 } |
432 | 432 |
433 | 433 |
434 int siItemFormatStrPrintDo(th_vprintf_ctx *ctx, th_vprintf_putch vputch, const char *fmt, | 434 int siItemFormatStrPrintDo(th_vprintf_ctx *ctx, th_vprintf_putch vputch, const char *fmt, |
435 const PSFOption *opt, const char *d_str, const int d_int) | 435 const int otype, const char *d_str, const int d_int) |
436 { | 436 { |
437 int ret = 0; | 437 int ret = 0; |
438 | 438 |
439 while (*fmt) | 439 while (*fmt) |
440 { | 440 { |
521 { | 521 { |
522 case 0: | 522 case 0: |
523 return -104; | 523 return -104; |
524 | 524 |
525 case 'o': | 525 case 'o': |
526 if (opt->type != OTYPE_INT) return -120; | 526 if (otype != OTYPE_INT) return -120; |
527 if ((ret = siItemFormatStrPutInt(ctx, vputch, d_int, 8, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_oct)) == EOF) | 527 if ((ret = siItemFormatStrPutInt(ctx, vputch, d_int, 8, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_oct)) == EOF) |
528 goto out; | 528 goto out; |
529 break; | 529 break; |
530 | 530 |
531 case 'u': | 531 case 'u': |
532 case 'i': | 532 case 'i': |
533 case 'd': | 533 case 'd': |
534 if (opt->type != OTYPE_INT) return -120; | 534 if (otype != OTYPE_INT) return -120; |
535 if ((ret = siItemFormatStrPutInt(ctx, vputch, d_int, 10, f_flags, f_width, f_prec, *fmt == 'u', NULL)) == EOF) | 535 if ((ret = siItemFormatStrPutInt(ctx, vputch, d_int, 10, f_flags, f_width, f_prec, *fmt == 'u', NULL)) == EOF) |
536 goto out; | 536 goto out; |
537 break; | 537 break; |
538 | 538 |
539 case 'x': | 539 case 'x': |
540 case 'X': | 540 case 'X': |
541 if (opt->type != OTYPE_INT) return -120; | 541 if (otype != OTYPE_INT) return -120; |
542 if (*fmt == 'X') | 542 if (*fmt == 'X') |
543 f_flags |= TH_PF_UPCASE; | 543 f_flags |= TH_PF_UPCASE; |
544 if ((ret = siItemFormatStrPutInt(ctx, vputch, d_int, 16, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_hex)) == EOF) | 544 if ((ret = siItemFormatStrPutInt(ctx, vputch, d_int, 16, f_flags, f_width, f_prec, TRUE, th_vprintf_altfmt_hex)) == EOF) |
545 goto out; | 545 goto out; |
546 break; | 546 break; |
547 | 547 |
548 case 's': | 548 case 's': |
549 if (opt->type != OTYPE_STR) return -121; | 549 if (otype != OTYPE_STR) return -121; |
550 if ((ret = th_vprintf_put_str(ctx, vputch, d_str, f_flags, f_width, f_prec)) == EOF) | 550 if ((ret = th_vprintf_put_str(ctx, vputch, d_str, f_flags, f_width, f_prec)) == EOF) |
551 goto out; | 551 goto out; |
552 break; | 552 break; |
553 | 553 |
554 //case '%': | 554 //case '%': |
581 ctx->ipos++; | 581 ctx->ipos++; |
582 return ch; | 582 return ch; |
583 } | 583 } |
584 | 584 |
585 | 585 |
586 char * siItemFormatStrPrint(const char *fmt, const PSFOption *opt, const char *d_str, const int d_int) | 586 char * siItemFormatStrPrint(const char *fmt, const int otype, const char *d_str, const int d_int) |
587 { | 587 { |
588 th_vprintf_ctx ctx; | 588 th_vprintf_ctx ctx; |
589 | 589 |
590 ctx.size = 128; | 590 ctx.size = 128; |
591 ctx.buf = th_malloc(ctx.size); | 591 ctx.buf = th_malloc(ctx.size); |
593 ctx.ipos = 0; | 593 ctx.ipos = 0; |
594 | 594 |
595 if (ctx.buf == NULL) | 595 if (ctx.buf == NULL) |
596 return NULL; | 596 return NULL; |
597 | 597 |
598 if (siItemFormatStrPrintDo(&ctx, siItemFormatStrPutCH, fmt, opt, d_str, d_int) <= 0) | 598 if (siItemFormatStrPrintDo(&ctx, siItemFormatStrPutCH, fmt, otype, d_str, d_int) <= 0) |
599 goto err; | 599 goto err; |
600 | 600 |
601 if (siItemFormatStrPutCH(&ctx, 0) < 0) | 601 if (siItemFormatStrPutCH(&ctx, 0) < 0) |
602 goto err; | 602 goto err; |
603 | 603 |
621 { | 621 { |
622 th_vprintf_ctx ctx; | 622 th_vprintf_ctx ctx; |
623 | 623 |
624 memset(&ctx, 0, sizeof(ctx)); | 624 memset(&ctx, 0, sizeof(ctx)); |
625 | 625 |
626 return siItemFormatStrPrintDo(&ctx, siItemFormatStrPutCHNone, fmt, opt, NULL, 0) >= 0; | 626 return siItemFormatStrPrintDo(&ctx, siItemFormatStrPutCHNone, fmt, opt->type, NULL, 0) >= 0; |
627 } | 627 } |
628 | 628 |
629 | 629 |
630 // | 630 // |
631 // Parse a format string into a PSFStack structure | 631 // Parse a format string into a PSFStack structure |
864 str++; | 864 str++; |
865 } | 865 } |
866 } | 866 } |
867 | 867 |
868 | 868 |
869 static void siPrintFieldPrefix(FILE *outFile, const PSFOption *opt) | 869 static void siPrintFieldPrefixName(FILE *outFile, const char *name) |
870 { | 870 { |
871 const char *name = (optParsable || opt->lname == NULL) ? opt->name : opt->lname; | |
872 if (!optNoNamePrefix && optFieldOutput) | 871 if (!optNoNamePrefix && optFieldOutput) |
873 fprintf(outFile, optParsable ? "%s=" : "%-20s : ", name); | 872 fprintf(outFile, optParsable ? "%s=" : "%-20s : ", name); |
874 } | 873 } |
875 | 874 |
876 | 875 |
876 static void siPrintFieldPrefix(FILE *outFile, const PSFOption *opt) | |
877 { | |
878 siPrintFieldPrefixName(outFile, | |
879 (optParsable || opt->lname == NULL) ? opt->name : opt->lname); | |
880 } | |
881 | |
882 | |
877 static void siPrintFieldSeparator(FILE *outFile) | 883 static void siPrintFieldSeparator(FILE *outFile) |
878 { | 884 { |
879 if (optFieldOutput) | 885 if (optFieldOutput) |
880 fputs(optOneLineFieldSep != NULL ? optOneLineFieldSep : "\n", outFile); | 886 fputs(optOneLineFieldSep != NULL ? optOneLineFieldSep : "\n", outFile); |
881 } | 887 } |
882 | 888 |
883 | 889 |
884 static void siPrintPSIDInfoLine(FILE *outFile, BOOL *shown, | 890 static const char *siGetInfoFormat(const PSFStackItem *item, const int otype) |
885 const PSFStackItem *item, const char *d_str, | 891 { |
886 const int d_int, const BOOL useConv) | 892 switch (otype) |
887 { | |
888 const PSFOption *opt = &optPSOptions[item->cmd]; | |
889 char *fmt, *str, *tmp; | |
890 | |
891 switch (opt->type) | |
892 { | 893 { |
893 case OTYPE_INT: | 894 case OTYPE_INT: |
894 if (item->flags & OFMT_FORMAT) | 895 if (item->flags & OFMT_FORMAT) |
895 fmt = item->fmt; | 896 return item->fmt; |
896 else | 897 else |
897 fmt = optHexadecimal ? "$%04x" : "%d"; | 898 return optHexadecimal ? "$%04x" : "%d"; |
898 break; | |
899 | 899 |
900 case OTYPE_STR: | 900 case OTYPE_STR: |
901 if (item->flags & OFMT_FORMAT) | 901 if (item->flags & OFMT_FORMAT) |
902 fmt = item->fmt; | 902 return item->fmt; |
903 else | 903 else |
904 fmt = "%s"; | 904 return "%s"; |
905 break; | |
906 | 905 |
907 default: | 906 default: |
908 return; | 907 return NULL; |
909 } | 908 } |
909 } | |
910 | |
911 | |
912 static void siPrintPSIDInfoLine(FILE *outFile, BOOL *shown, | |
913 const char *fmt, const int otype, | |
914 const char *d_str, const int d_int, | |
915 const BOOL useConv) | |
916 { | |
917 char *str, *tmp; | |
910 | 918 |
911 if (setUseChConv && d_str != NULL && useConv) | 919 if (setUseChConv && d_str != NULL && useConv) |
912 { | 920 { |
913 char *tmp2 = siConvertCharset(d_str); | 921 char *tmp2 = siConvertCharset(d_str); |
914 tmp = siEscapeString(tmp2, optEscapeChars); | 922 tmp = siEscapeString(tmp2, optEscapeChars); |
915 th_free(tmp2); | 923 th_free(tmp2); |
916 } | 924 } |
917 else | 925 else |
918 tmp = siEscapeString(d_str, optEscapeChars); | 926 tmp = siEscapeString(d_str, optEscapeChars); |
919 | 927 |
920 siPrintFieldPrefix(outFile, opt); | 928 if ((str = siItemFormatStrPrint(fmt, otype, tmp, d_int)) != NULL) |
921 | |
922 if ((str = siItemFormatStrPrint(fmt, opt, tmp, d_int)) != NULL) | |
923 fputs(str, outFile); | 929 fputs(str, outFile); |
924 | 930 |
925 siPrintFieldSeparator(outFile); | 931 siPrintFieldSeparator(outFile); |
932 | |
926 th_free(str); | 933 th_free(str); |
927 th_free(tmp); | 934 th_free(tmp); |
928 | 935 |
929 *shown = TRUE; | 936 *shown = TRUE; |
930 } | 937 } |
931 | 938 |
932 | 939 |
933 #define PRS(d_str, d_conv) siPrintPSIDInfoLine(outFile, shown, item, d_str, -1, d_conv) | 940 #define PRS(d_str, d_conv) do { \ |
934 #define PRI(d_int) siPrintPSIDInfoLine(outFile, shown, item, NULL, d_int, FALSE) | 941 siPrintFieldPrefix(outFile, opt); \ |
942 siPrintPSIDInfoLine(outFile, shown, siGetInfoFormat(item, opt->type), opt->type, d_str, -1, d_conv); \ | |
943 } while (0) | |
944 | |
945 #define PRI(d_int) do { \ | |
946 siPrintFieldPrefix(outFile, opt); \ | |
947 siPrintPSIDInfoLine(outFile, shown, siGetInfoFormat(item, opt->type), opt->type, NULL, d_int, FALSE); \ | |
948 } while (0) | |
935 | 949 |
936 | 950 |
937 static void siPrintPSIDInformationField(FILE *outFile, const char *filename, | 951 static void siPrintPSIDInformationField(FILE *outFile, const char *filename, |
938 const SIDLibPSIDHeader *psid, BOOL *shown, const PSFStackItem *item) | 952 const SIDLibPSIDHeader *psid, BOOL *shown, const PSFStackItem *item) |
939 { | 953 { |