Mercurial > hg > dmlib
comparison tools/gfxconv.c @ 1889:ac9784afae27
Improve option argument parsing.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 25 Jun 2018 17:10:24 +0300 |
parents | b97f273a9d54 |
children | ee95059b4c18 |
comparison
equal
deleted
inserted
replaced
1888:b97f273a9d54 | 1889:ac9784afae27 |
---|---|
126 { 17, 'F', "formats", "List supported input/output formats", OPT_NONE }, | 126 { 17, 'F', "formats", "List supported input/output formats", OPT_NONE }, |
127 { 8, 'q', "sequential", "Output sequential files (image output only)", OPT_NONE }, | 127 { 8, 'q', "sequential", "Output sequential files (image output only)", OPT_NONE }, |
128 { 6, 'c', "colormap", "Color mappings (see below for information)", OPT_ARGREQ }, | 128 { 6, 'c', "colormap", "Color mappings (see below for information)", OPT_ARGREQ }, |
129 { 7, 'n', "numitems", "How many 'items' to output (default: all)", OPT_ARGREQ }, | 129 { 7, 'n', "numitems", "How many 'items' to output (default: all)", OPT_ARGREQ }, |
130 { 11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ }, | 130 { 11, 'w', "width", "Item width (number of items per row, min 1)", OPT_ARGREQ }, |
131 { 9, 'S', "scale", "Scale output image by <n> or <x>:<y> integer factor(s). " | 131 { 9, 'S', "scale", "Scale output image by <n>, <x>:<y>, <x>:<y>*<n> integer factor(s). " |
132 "-S <n> scales both height and width by <n>.", OPT_ARGREQ }, | 132 "-S <n> scales both height and width by <n>. -S <x>:<y>*<n> scales " |
133 "width by X*n and height Y*n.", OPT_ARGREQ }, | |
133 { 12, 'P', "paletted", "Use indexed/paletted output IF possible.", OPT_NONE }, | 134 { 12, 'P', "paletted", "Use indexed/paletted output IF possible.", OPT_NONE }, |
134 { 13, 'N', "nplanes", "# of bitplanes (some output formats)", OPT_ARGREQ }, | 135 { 13, 'N', "nplanes", "# of bitplanes (some output formats)", OPT_ARGREQ }, |
135 { 18, 'B', "bpp", "Bits per pixel (some output formats)", OPT_ARGREQ }, | 136 { 18, 'B', "bpp", "Bits per pixel (some output formats)", OPT_ARGREQ }, |
136 { 14, 'I', "interleave", "Interleaved/planar output (some output formats)", OPT_NONE }, | 137 { 14, 'I', "interleave", "Interleaved/planar output (some output formats)", OPT_NONE }, |
137 { 16, 'R', "remap", "Remap output image colors (-R <(#RRGGBB|index):index>[,<..>][+remove] | -R @map.txt[+remove])", OPT_ARGREQ }, | 138 { 16, 'R', "remap", "Remap output image colors (-R <(#RRGGBB|index):index>[,<..>][+remove] | -R @map.txt[+remove])", OPT_ARGREQ }, |
557 | 558 |
558 return TRUE; | 559 return TRUE; |
559 } | 560 } |
560 | 561 |
561 | 562 |
562 BOOL dmParseIntValWithSep(char **arg, int *value, char *end, const char sep) | 563 BOOL dmParseIntValWithSep(char **arg, unsigned int *value, char *last, const char sep) |
563 { | 564 { |
564 unsigned int val; | 565 char *ptr = *arg, *end, *start; |
565 char *ptr = *arg, *ptr2; | |
566 BOOL ret; | |
567 | 566 |
568 // Skip any whitespace at start | 567 // Skip any whitespace at start |
569 while (*ptr != 0 && isspace(*ptr)) | 568 while (*ptr != 0 && isspace(*ptr)) |
570 ptr++; | 569 ptr++; |
571 | 570 |
572 // Find end of non-whitespace | 571 start = ptr; |
573 while (*ptr != 0 && (isxdigit(*ptr) || *ptr == 'x' || *ptr == '$') && *ptr != sep) | 572 |
573 // Find next not-xdigit/separator | |
574 while (*ptr != 0 && | |
575 (isxdigit(*ptr) || *ptr == 'x' || *ptr == '$') && | |
576 *ptr != sep) | |
574 ptr++; | 577 ptr++; |
575 | 578 |
576 ptr2 = ptr; | 579 end = ptr; |
577 | 580 |
578 // Skip whitespace again | 581 // Skip whitespace again |
579 while (*ptr != 0 && isspace(*ptr)) | 582 while (*ptr != 0 && isspace(*ptr)) |
580 ptr++; | 583 ptr++; |
581 | 584 |
582 *end = *ptr; | 585 // Return last character in "last" |
583 *ptr2 = 0; | 586 *last = *ptr; |
584 if (*end != 0) | 587 |
588 // Set end to NUL | |
589 *end = 0; | |
590 | |
591 // And if last character is not NUL, move ptr | |
592 if (*last != 0) | |
585 ptr++; | 593 ptr++; |
586 | 594 |
587 ret = dmGetIntVal(*arg, &val); | |
588 *arg = ptr; | 595 *arg = ptr; |
589 *value = val; | 596 |
590 return ret; | 597 return dmGetIntVal(start, value); |
591 } | 598 } |
592 | 599 |
593 | 600 |
594 BOOL argHandleOpt(const int optN, char *optArg, char *currArg) | 601 BOOL argHandleOpt(const int optN, char *optArg, char *currArg) |
595 { | 602 { |
596 int tmpInt; | 603 unsigned int tmpUInt; |
597 char *tmpStr; | 604 char *tmpStr; |
598 | 605 |
599 switch (optN) | 606 switch (optN) |
600 { | 607 { |
601 case 0: | 608 case 0: |
675 dmPrint(1, "\n"); | 682 dmPrint(1, "\n"); |
676 } | 683 } |
677 break; | 684 break; |
678 | 685 |
679 case 7: | 686 case 7: |
680 if (sscanf(optArg, "%d", &optItemCount) != 1) | 687 if (!dmGetIntVal(optArg, &tmpUInt) || |
681 { | 688 tmpUInt < 1) |
682 dmErrorMsg("Invalid count value argument '%s'.\n", optArg); | 689 { |
690 dmErrorMsg("Invalid count value argument '%s' [1 .. MAXINT]\n", | |
691 optArg); | |
683 return FALSE; | 692 return FALSE; |
684 } | 693 } |
694 optItemCount = tmpUInt; | |
685 break; | 695 break; |
686 | 696 |
687 case 8: | 697 case 8: |
688 optSequential = TRUE; | 698 optSequential = TRUE; |
689 break; | 699 break; |
690 | 700 |
691 case 9: | 701 case 9: |
692 { | 702 { |
693 BOOL error = FALSE; | 703 BOOL error = FALSE; |
704 unsigned int tmpUInt2; | |
694 char *tmpStr = dm_strdup(optArg), | 705 char *tmpStr = dm_strdup(optArg), |
695 *tmpOpt = tmpStr, sep; | 706 *tmpOpt = tmpStr, sep; |
696 | 707 |
697 if (dmParseIntValWithSep(&tmpOpt, &tmpInt, &sep, ':')) | 708 if (dmParseIntValWithSep(&tmpOpt, &tmpUInt, &sep, ':')) |
698 { | 709 { |
699 if (sep == ':' && | 710 if (sep == ':' && |
700 dmParseIntValWithSep(&tmpOpt, &optSpec.scaleY, &sep, '*')) | 711 dmParseIntValWithSep(&tmpOpt, &tmpUInt2, &sep, '*')) |
701 { | 712 { |
702 optSpec.scaleX = tmpInt; | 713 optSpec.scaleX = tmpUInt; |
714 optSpec.scaleY = tmpUInt2; | |
715 | |
703 if (sep == '*' && | 716 if (sep == '*' && |
704 dmParseIntValWithSep(&tmpOpt, &tmpInt, &sep, 0)) | 717 dmParseIntValWithSep(&tmpOpt, &tmpUInt, &sep, 0)) |
705 { | 718 { |
706 optSpec.scaleX *= tmpInt; | 719 optSpec.scaleX *= tmpUInt; |
707 optSpec.scaleY *= tmpInt; | 720 optSpec.scaleY *= tmpUInt; |
708 } | 721 } |
709 | |
710 error = (sep != 0); | 722 error = (sep != 0); |
711 } | 723 } |
712 else | 724 else |
713 error = TRUE; | 725 error = TRUE; |
714 } | 726 } |
725 return FALSE; | 737 return FALSE; |
726 } | 738 } |
727 | 739 |
728 if (optSpec.scaleX < 1 || optSpec.scaleX > 50) | 740 if (optSpec.scaleX < 1 || optSpec.scaleX > 50) |
729 { | 741 { |
730 dmErrorMsg("Invalid X scale value '%d'.\n", optSpec.scaleX); | 742 dmErrorMsg("Invalid X scale value %d.\n", optSpec.scaleX); |
731 return FALSE; | 743 return FALSE; |
732 } | 744 } |
733 if (optSpec.scaleY < 1 || optSpec.scaleY > 50) | 745 if (optSpec.scaleY < 1 || optSpec.scaleY > 50) |
734 { | 746 { |
735 dmErrorMsg("Invalid Y scale value '%d'.\n", optSpec.scaleY); | 747 dmErrorMsg("Invalid Y scale value %d.\n", optSpec.scaleY); |
736 return FALSE; | 748 return FALSE; |
737 } | 749 } |
738 } | 750 } |
739 break; | 751 break; |
740 | 752 |
741 case 11: | 753 case 11: |
742 if (sscanf(optArg, "%d", &optPlanedWidth) != 1) | 754 if (!dmGetIntVal(optArg, &tmpUInt) || |
743 { | 755 tmpUInt < 1 || tmpUInt > 512) |
744 dmErrorMsg("Invalid planed width value argument '%s'.\n", | 756 { |
757 dmErrorMsg("Invalid planed width value '%s' [1 .. 512]\n", | |
745 optArg); | 758 optArg); |
746 return FALSE; | 759 return FALSE; |
747 } | 760 } |
748 if (optPlanedWidth < 1 || optPlanedWidth > 512) | 761 optPlanedWidth = tmpUInt; |
749 { | |
750 dmErrorMsg("Invalid planed width value '%d' [1..512].\n", | |
751 optPlanedWidth); | |
752 return FALSE; | |
753 } | |
754 break; | 762 break; |
755 | 763 |
756 case 12: | 764 case 12: |
757 optSpec.paletted = TRUE; | 765 optSpec.paletted = TRUE; |
758 break; | 766 break; |
759 | 767 |
760 case 13: | 768 case 13: |
761 if (sscanf(optArg, "%d", &tmpInt) != 1 || | 769 if (!dmGetIntVal(optArg, &tmpUInt) || |
762 tmpInt < 1 || tmpInt > 8) | 770 tmpUInt < 1 || tmpUInt > 8) |
763 { | 771 { |
764 dmErrorMsg("Invalid number of bitplanes value '%s' [1..8].\n", | 772 dmErrorMsg("Invalid number of bitplanes value '%s' [1 .. 8]\n", |
765 optArg); | 773 optArg); |
766 return FALSE; | 774 return FALSE; |
767 } | 775 } |
768 optSpec.nplanes = tmpInt; | 776 optSpec.nplanes = tmpUInt; |
769 break; | 777 break; |
770 | 778 |
771 case 18: | 779 case 18: |
772 if (sscanf(optArg, "%d", &tmpInt) != 1 || | 780 if (!dmGetIntVal(optArg, &tmpUInt) || |
773 tmpInt < 1 || tmpInt > 32) | 781 tmpUInt < 1 || tmpUInt > 32) |
774 { | 782 { |
775 dmErrorMsg("Invalid number of bits per pixel value '%s' [1..32].\n", | 783 dmErrorMsg("Invalid number of bits per pixel value '%s' [1 .. 32]\n", |
776 optArg); | 784 optArg); |
777 return FALSE; | 785 return FALSE; |
778 } | 786 } |
779 optSpec.nplanes = tmpInt; | 787 optSpec.nplanes = tmpUInt; |
780 break; | 788 break; |
781 | 789 |
782 case 14: | 790 case 14: |
783 optSpec.planar = TRUE; | 791 optSpec.planar = TRUE; |
784 break; | 792 break; |