Changeset 1b20da0 in mainline for uspace/lib/c/generic/io/printf_core.c
- Timestamp:
- 2018-02-28T17:52:03Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3061bc1
- Parents:
- df6ded8
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:26:03)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:52:03)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/io/printf_core.c
rdf6ded8 r1b20da0 592 592 593 593 /** Prints a special double (ie NaN, infinity) padded to width characters. */ 594 static int print_special(ieee_double_t val, int width, uint32_t flags, 594 static int print_special(ieee_double_t val, int width, uint32_t flags, 595 595 printf_spec_t *ps) 596 596 { … … 615 615 /* Leading padding. */ 616 616 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 617 if ((ret = print_padding(' ', padding_len, ps)) < 0) 617 if ((ret = print_padding(' ', padding_len, ps)) < 0) 618 618 return -1; 619 619 … … 636 636 /* Trailing padding. */ 637 637 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 638 if ((ret = print_padding(' ', padding_len, ps)) < 0) 638 if ((ret = print_padding(' ', padding_len, ps)) < 0) 639 639 return -1; 640 640 … … 698 698 699 699 700 /** Format and print the double string repressentation according 701 * to the %f specifier. 702 */ 703 static int print_double_str_fixed(double_str_t *val_str, int precision, int width, 700 /** Format and print the double string repressentation according 701 * to the %f specifier. 702 */ 703 static int print_double_str_fixed(double_str_t *val_str, int precision, int width, 704 704 uint32_t flags, printf_spec_t *ps) 705 705 { … … 742 742 743 743 if (!(flags & (__PRINTF_FLAG_LEFTALIGNED | __PRINTF_FLAG_ZEROPADDED))) { 744 if ((ret = print_padding(' ', padding_len, ps)) < 0) 744 if ((ret = print_padding(' ', padding_len, ps)) < 0) 745 745 return -1; 746 746 … … 749 749 750 750 if (sign) { 751 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 751 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 752 752 return -1; 753 753 … … 756 756 757 757 if (flags & __PRINTF_FLAG_ZEROPADDED) { 758 if ((ret = print_padding('0', padding_len, ps)) < 0) 758 if ((ret = print_padding('0', padding_len, ps)) < 0) 759 759 return -1; 760 760 … … 767 767 768 768 if (0 < buf_int_len) { 769 if ((ret = ps->str_write(buf, buf_int_len, ps->data)) < 0) 769 if ((ret = ps->str_write(buf, buf_int_len, ps->data)) < 0) 770 770 return -1; 771 771 … … 773 773 774 774 /* Print trailing zeros of the integral part of the number. */ 775 if ((ret = print_padding('0', int_len - buf_int_len, ps)) < 0) 775 if ((ret = print_padding('0', int_len - buf_int_len, ps)) < 0) 776 776 return -1; 777 777 } else { 778 778 /* Single leading integer 0. */ 779 779 char ch = '0'; 780 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 780 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 781 781 return -1; 782 782 } … … 788 788 char ch = '.'; 789 789 790 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 790 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 791 791 return -1; 792 792 … … 794 794 795 795 /* Print leading zeros of the fractional part of the number. */ 796 if ((ret = print_padding('0', leading_frac_zeros, ps)) < 0) 796 if ((ret = print_padding('0', leading_frac_zeros, ps)) < 0) 797 797 return -1; 798 798 … … 801 801 /* Print significant digits of the fractional part of the number. */ 802 802 if (0 < signif_frac_figs) { 803 if ((ret = ps->str_write(buf_frac, signif_frac_figs, ps->data)) < 0) 803 if ((ret = ps->str_write(buf_frac, signif_frac_figs, ps->data)) < 0) 804 804 return -1; 805 805 … … 808 808 809 809 /* Print trailing zeros of the fractional part of the number. */ 810 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 810 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 811 811 return -1; 812 812 … … 816 816 /* Trailing padding. */ 817 817 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 818 if ((ret = print_padding(' ', padding_len, ps)) < 0) 818 if ((ret = print_padding(' ', padding_len, ps)) < 0) 819 819 return -1; 820 820 … … 826 826 827 827 828 /** Convert, format and print a double according to the %f specifier. 828 /** Convert, format and print a double according to the %f specifier. 829 829 * 830 830 * @param g Double to print. … … 832 832 * decimal point will be printed unless the flag 833 833 * __PRINTF_FLAG_DECIMALPT is specified. 834 * @param width Minimum number of characters to display. Pads 834 * @param width Minimum number of characters to display. Pads 835 835 * with '0' or ' ' depending on the set flags; 836 836 * @param flags Printf flags. … … 839 839 * @return The number of characters printed; negative on failure. 840 840 */ 841 static int print_double_fixed(double g, int precision, int width, uint32_t flags, 841 static int print_double_fixed(double g, int precision, int width, uint32_t flags, 842 842 printf_spec_t *ps) 843 843 { … … 854 854 if (val.is_special) { 855 855 return print_special(val, width, flags, ps); 856 } 856 } 857 857 858 858 char buf[MAX_DOUBLE_STR_BUF_SIZE]; … … 864 864 865 865 if (0 <= precision) { 866 /* 866 /* 867 867 * Request one more digit so we can round the result. The last 868 * digit it returns may have an error of at most +/- 1. 868 * digit it returns may have an error of at most +/- 1. 869 869 */ 870 val_str.len = double_to_fixed_str(val, -1, precision + 1, buf, buf_size, 870 val_str.len = double_to_fixed_str(val, -1, precision + 1, buf, buf_size, 871 871 &val_str.dec_exp); 872 872 873 /* 874 * Round using the last digit to produce precision fractional digits. 875 * If less than precision+1 fractional digits were output the last 876 * digit is definitely inaccurate so also round to get rid of it. 873 /* 874 * Round using the last digit to produce precision fractional digits. 875 * If less than precision+1 fractional digits were output the last 876 * digit is definitely inaccurate so also round to get rid of it. 877 877 */ 878 878 fp_round_up(buf, &val_str.len, &val_str.dec_exp); … … 901 901 char exp_ch = (flags & __PRINTF_FLAG_BIGCHARS) ? 'E' : 'e'; 902 902 903 if ((ret = ps->str_write(&exp_ch, 1, ps->data)) < 0) 903 if ((ret = ps->str_write(&exp_ch, 1, ps->data)) < 0) 904 904 return -1; 905 905 … … 925 925 const char *exp_str_start = &exp_str[3] - exp_len; 926 926 927 if ((ret = ps->str_write(exp_str_start, exp_len, ps->data)) < 0) 927 if ((ret = ps->str_write(exp_str_start, exp_len, ps->data)) < 0) 928 928 return -1; 929 929 … … 934 934 935 935 936 /** Format and print the double string repressentation according 937 * to the %e specifier. 938 */ 939 static int print_double_str_scient(double_str_t *val_str, int precision, 936 /** Format and print the double string repressentation according 937 * to the %e specifier. 938 */ 939 static int print_double_str_scient(double_str_t *val_str, int precision, 940 940 int width, uint32_t flags, printf_spec_t *ps) 941 941 { … … 972 972 973 973 if (!(flags & (__PRINTF_FLAG_LEFTALIGNED | __PRINTF_FLAG_ZEROPADDED))) { 974 if ((ret = print_padding(' ', padding_len, ps)) < 0) 974 if ((ret = print_padding(' ', padding_len, ps)) < 0) 975 975 return -1; 976 976 … … 979 979 980 980 if (sign) { 981 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 981 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 982 982 return -1; 983 983 … … 986 986 987 987 if (flags & __PRINTF_FLAG_ZEROPADDED) { 988 if ((ret = print_padding('0', padding_len, ps)) < 0) 988 if ((ret = print_padding('0', padding_len, ps)) < 0) 989 989 return -1; 990 990 … … 993 993 994 994 /* Single leading integer. */ 995 if ((ret = ps->str_write(buf, 1, ps->data)) < 0) 995 if ((ret = ps->str_write(buf, 1, ps->data)) < 0) 996 996 return -1; 997 997 … … 1002 1002 char ch = '.'; 1003 1003 1004 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 1004 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 1005 1005 return -1; 1006 1006 … … 1009 1009 /* Print significant digits of the fractional part of the number. */ 1010 1010 if (0 < signif_frac_figs) { 1011 if ((ret = ps->str_write(buf + 1, signif_frac_figs, ps->data)) < 0) 1011 if ((ret = ps->str_write(buf + 1, signif_frac_figs, ps->data)) < 0) 1012 1012 return -1; 1013 1013 … … 1016 1016 1017 1017 /* Print trailing zeros of the fractional part of the number. */ 1018 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 1018 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 1019 1019 return -1; 1020 1020 … … 1023 1023 1024 1024 /* Print the exponent. */ 1025 if ((ret = print_exponent(exp_val, flags, ps)) < 0) 1025 if ((ret = print_exponent(exp_val, flags, ps)) < 0) 1026 1026 return -1; 1027 1027 … … 1029 1029 1030 1030 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 1031 if ((ret = print_padding(' ', padding_len, ps)) < 0) 1031 if ((ret = print_padding(' ', padding_len, ps)) < 0) 1032 1032 return -1; 1033 1033 … … 1039 1039 1040 1040 1041 /** Convert, format and print a double according to the %e specifier. 1042 * 1043 * Note that if g is large, the output may be huge (3e100 prints 1041 /** Convert, format and print a double according to the %e specifier. 1042 * 1043 * Note that if g is large, the output may be huge (3e100 prints 1044 1044 * with at least 100 digits). 1045 1045 * … … 1054 1054 * __PRINTF_FLAG_DECIMALPT is specified. If negative 1055 1055 * the shortest accurate number will be printed. 1056 * @param width Minimum number of characters to display. Pads 1056 * @param width Minimum number of characters to display. Pads 1057 1057 * with '0' or ' ' depending on the set flags; 1058 1058 * @param flags Printf flags. … … 1061 1061 * @return The number of characters printed; negative on failure. 1062 1062 */ 1063 static int print_double_scientific(double g, int precision, int width, 1063 static int print_double_scientific(double g, int precision, int width, 1064 1064 uint32_t flags, printf_spec_t *ps) 1065 1065 { … … 1072 1072 if (val.is_special) { 1073 1073 return print_special(val, width, flags, ps); 1074 } 1074 } 1075 1075 1076 1076 char buf[MAX_DOUBLE_STR_BUF_SIZE]; … … 1082 1082 1083 1083 if (0 <= precision) { 1084 /* 1085 * Request one more digit (in addition to the leading integer) 1086 * so we can round the result. The last digit it returns may 1087 * have an error of at most +/- 1. 1084 /* 1085 * Request one more digit (in addition to the leading integer) 1086 * so we can round the result. The last digit it returns may 1087 * have an error of at most +/- 1. 1088 1088 */ 1089 val_str.len = double_to_fixed_str(val, precision + 2, -1, buf, buf_size, 1089 val_str.len = double_to_fixed_str(val, precision + 2, -1, buf, buf_size, 1090 1090 &val_str.dec_exp); 1091 1091 1092 /* 1093 * Round the extra digit to produce precision+1 significant digits. 1094 * If less than precision+2 significant digits were returned the last 1095 * digit is definitely inaccurate so also round to get rid of it. 1092 /* 1093 * Round the extra digit to produce precision+1 significant digits. 1094 * If less than precision+2 significant digits were returned the last 1095 * digit is definitely inaccurate so also round to get rid of it. 1096 1096 */ 1097 1097 fp_round_up(buf, &val_str.len, &val_str.dec_exp); … … 1113 1113 1114 1114 1115 /** Convert, format and print a double according to the %g specifier. 1116 * 1117 * %g style chooses between %f and %e. 1115 /** Convert, format and print a double according to the %g specifier. 1116 * 1117 * %g style chooses between %f and %e. 1118 1118 * 1119 1119 * @param g Double to print. … … 1121 1121 * any leading zeros from this count. If negative 1122 1122 * the shortest accurate number will be printed. 1123 * @param width Minimum number of characters to display. Pads 1123 * @param width Minimum number of characters to display. Pads 1124 1124 * with '0' or ' ' depending on the set flags; 1125 1125 * @param flags Printf flags. … … 1128 1128 * @return The number of characters printed; negative on failure. 1129 1129 */ 1130 static int print_double_generic(double g, int precision, int width, 1130 static int print_double_generic(double g, int precision, int width, 1131 1131 uint32_t flags, printf_spec_t *ps) 1132 1132 { … … 1135 1135 if (val.is_special) { 1136 1136 return print_special(val, width, flags, ps); 1137 } 1137 } 1138 1138 1139 1139 char buf[MAX_DOUBLE_STR_BUF_SIZE]; … … 1144 1144 /* Honor the user requested number of significant digits. */ 1145 1145 if (0 <= precision) { 1146 /* 1147 * Do a quick and dirty conversion of a single digit to determine 1146 /* 1147 * Do a quick and dirty conversion of a single digit to determine 1148 1148 * the decimal exponent. 1149 1149 */ … … 1155 1155 if (-4 <= dec_exp && dec_exp < precision) { 1156 1156 precision = precision - (dec_exp + 1); 1157 return print_double_fixed(g, precision, width, 1157 return print_double_fixed(g, precision, width, 1158 1158 flags | __PRINTF_FLAG_NOFRACZEROS, ps); 1159 1159 } else { 1160 1160 --precision; 1161 return print_double_scientific(g, precision, width, 1161 return print_double_scientific(g, precision, width, 1162 1162 flags | __PRINTF_FLAG_NOFRACZEROS, ps); 1163 1163 } … … 1194 1194 1195 1195 1196 /** Convert, format and print a double according to the specifier. 1196 /** Convert, format and print a double according to the specifier. 1197 1197 * 1198 1198 * Depending on the specifier it prints the double using the styles … … 1206 1206 * the shortest accurate number will be printed for style %g; 1207 1207 * negative precision defaults to 6 for styles %f, %e. 1208 * @param width Minimum number of characters to display. Pads 1208 * @param width Minimum number of characters to display. Pads 1209 1209 * with '0' or ' ' depending on the set flags; 1210 1210 * @param flags Printf flags. … … 1213 1213 * @return The number of characters printed; negative on failure. 1214 1214 */ 1215 static int print_double(double g, char spec, int precision, int width, 1215 static int print_double(double g, char spec, int precision, int width, 1216 1216 uint32_t flags, printf_spec_t *ps) 1217 1217 { … … 1542 1542 case 'E': 1543 1543 case 'e': 1544 retval = print_double(va_arg(ap, double), uc, precision, 1544 retval = print_double(va_arg(ap, double), uc, precision, 1545 1545 width, flags, ps); 1546 1546
Note:
See TracChangeset
for help on using the changeset viewer.