Changes in / [508fff8:f220e25] in mainline
- Location:
- uspace
- Files:
-
- 8 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/config.h
r508fff8 rf220e25 55 55 #define PACKAGE_STRING "The brain dead shell" 56 56 #define PACKAGE_TARNAME "bdsh" 57 #define PACKAGE_VERSION "0.0.1" 58 59 60 57 #define PACKAGE_VERSION "0.1.0" -
uspace/app/tester/Makefile
r508fff8 rf220e25 42 42 print/print4.c \ 43 43 print/print5.c \ 44 print/print6.c \ 44 45 console/console1.c \ 45 46 stdio/stdio1.c \ -
uspace/app/tester/float/softfloat1.c
r508fff8 rf220e25 34 34 #include <mul.h> 35 35 #include <div.h> 36 #include <comparison.h> 36 37 #include <bool.h> 37 38 #include "../tester.h" … … 45 46 typedef void (* float_op_t)(float, float, float *, float_t *); 46 47 typedef void (* double_op_t)(double, double, double *, double_t *); 48 typedef void (* double_cmp_op_t)(double, double, cmptype_t *, cmptype_t *); 47 49 typedef void (* template_t)(void *, unsigned, unsigned, cmptype_t *, 48 50 cmptype_t *); … … 66 68 67 69 return -a; 70 } 71 72 static int dcmp(double a, double b) 73 { 74 if (a < b) 75 return -1; 76 else if (a > b) 77 return 1; 78 79 return 0; 68 80 } 69 81 … … 96 108 *pic = (cmptype_t) (c * PRECISION); 97 109 *pisc = (cmptype_t) (sc.val * PRECISION); 110 } 111 112 static void 113 double_compare_template(void *f, unsigned i, unsigned j, cmptype_t *pis, 114 cmptype_t *piss) 115 { 116 double_cmp_op_t op = (double_cmp_op_t) f; 117 118 op(dop_a[i], dop_b[j], pis, piss); 98 119 } 99 120 … … 221 242 } 222 243 244 static void 245 double_cmp_operator(double a, double b, cmptype_t *pis, cmptype_t *piss) 246 { 247 *pis = dcmp(a, b); 248 249 double_t sa; 250 double_t sb; 251 252 sa.val = a; 253 sb.val = b; 254 255 if (is_double_lt(sa.data, sb.data)) 256 *piss = -1; 257 else if (is_double_gt(sa.data, sb.data)) 258 *piss = 1; 259 else if (is_double_eq(sa.data, sb.data)) 260 *piss = 0; 261 else 262 *piss = 42; 263 } 264 223 265 const char *test_softfloat1(void) 224 266 { … … 249 291 TPRINTF("%s\n", err); 250 292 } 293 if (!test_template(double_compare_template, double_cmp_operator)) { 294 err = "Double comparison failed"; 295 TPRINTF("%s\n", err); 296 } 251 297 252 298 return err; -
uspace/app/tester/print/print5.def
r508fff8 rf220e25 1 1 { 2 "print 1",3 " Stringprintf test",4 &test_print 1,2 "print5", 3 "Char printf test", 4 &test_print5, 5 5 true 6 6 }, -
uspace/app/tester/tester.c
r508fff8 rf220e25 53 53 #include "print/print4.def" 54 54 #include "print/print5.def" 55 #include "print/print6.def" 55 56 #include "console/console1.def" 56 57 #include "stdio/stdio1.def" -
uspace/app/tester/tester.h
r508fff8 rf220e25 85 85 extern const char *test_print4(void); 86 86 extern const char *test_print5(void); 87 extern const char *test_print6(void); 87 88 extern const char *test_console1(void); 88 89 extern const char *test_stdio1(void); -
uspace/lib/c/Makefile
r508fff8 rf220e25 77 77 generic/device/pci.c \ 78 78 generic/device/ahci.c \ 79 generic/dlfcn.c \ 79 80 generic/elf/elf_load.c \ 80 81 generic/event.c \ … … 115 116 generic/iplink.c \ 116 117 generic/iplink_srv.c \ 118 generic/ieee_double.c \ 119 generic/power_of_ten.c \ 120 generic/double_to_str.c \ 117 121 generic/malloc.c \ 118 122 generic/sysinfo.c \ … … 144 148 ifeq ($(CONFIG_RTLD),y) 145 149 GENERIC_SOURCES += \ 146 generic/dlfcn.c \147 150 generic/rtld/rtld.c \ 148 151 generic/rtld/dynamic.c \ -
uspace/lib/c/generic/dlfcn.c
r508fff8 rf220e25 38 38 #include <stdlib.h> 39 39 #include <dlfcn.h> 40 41 #ifdef CONFIG_RTLD 40 42 41 43 #include <rtld/module.h> … … 87 89 } 88 90 91 #else /* CONFIG_RTLD not defined */ 92 93 void *dlopen(const char *path, int flag) 94 { 95 return NULL; 96 } 97 98 void *dlsym(void *mod, const char *sym_name) 99 { 100 return NULL; 101 } 102 103 #endif 104 89 105 /** @} 90 106 */ -
uspace/lib/c/generic/io/log.c
r508fff8 rf220e25 239 239 240 240 char *message_buffer = malloc(MESSAGE_BUFFER_SIZE); 241 if (message_buffer == NULL) {241 if (message_buffer == NULL) 242 242 return; 243 }244 243 245 244 vsnprintf(message_buffer, MESSAGE_BUFFER_SIZE, fmt, args); 246 245 logger_message(logger_session, ctx, level, message_buffer); 246 free(message_buffer); 247 247 } 248 248 -
uspace/lib/c/generic/io/printf_core.c
r508fff8 rf220e25 42 42 #include <ctype.h> 43 43 #include <str.h> 44 #include <double_to_str.h> 45 #include <ieee_double.h> 46 #include <assert.h> 47 #include <macros.h> 48 44 49 45 50 /** show prefixes 0x or 0 */ 46 51 #define __PRINTF_FLAG_PREFIX 0x00000001 47 52 53 /** show the decimal point even if no fractional digits present */ 54 #define __PRINTF_FLAG_DECIMALPT 0x00000001 55 48 56 /** signed / unsigned number */ 49 57 #define __PRINTF_FLAG_SIGNED 0x00000002 … … 66 74 /** number has - sign */ 67 75 #define __PRINTF_FLAG_NEGATIVE 0x00000100 76 77 /** don't print trailing zeros in the fractional part */ 78 #define __PRINTF_FLAG_NOFRACZEROS 0x00000200 79 68 80 69 81 /** … … 110 122 static const char invalch = U_SPECIAL; 111 123 124 125 126 /** Unformatted double number string representation. */ 127 typedef struct { 128 /** Buffer with len digits, no sign or leading zeros. */ 129 char *str; 130 /** Number of digits in str. */ 131 int len; 132 /** Decimal exponent, ie number = str * 10^dec_exp */ 133 int dec_exp; 134 /** True if negative. */ 135 bool neg; 136 } double_str_t; 137 138 139 140 /** Returns the sign character or 0 if no sign should be printed. */ 141 static int get_sign_char(bool negative, uint32_t flags) 142 { 143 if (negative) { 144 return '-'; 145 } else if (flags & __PRINTF_FLAG_SHOWPLUS) { 146 return '+'; 147 } else if (flags & __PRINTF_FLAG_SPACESIGN) { 148 return ' '; 149 } else { 150 return 0; 151 } 152 } 153 154 /** Prints count times character ch. */ 155 static int print_padding(char ch, int count, printf_spec_t *ps) 156 { 157 for (int i = 0; i < count; ++i) { 158 if (ps->str_write(&ch, 1, ps->data) < 0) { 159 return -1; 160 } 161 } 162 163 return count; 164 } 165 166 112 167 /** Print one or more characters without adding newline. 113 168 * … … 281 336 return printf_putstr(nullstr, ps); 282 337 283 /* Print leading spaces. */284 338 size_t strw = str_length(str); 339 340 /* Precision unspecified - print everything. */ 285 341 if ((precision == 0) || (precision > strw)) 286 342 precision = strw; … … 329 385 return printf_putstr(nullstr, ps); 330 386 331 /* Print leading spaces. */332 387 size_t strw = wstr_length(str); 388 389 /* Precision not specified - print everything. */ 333 390 if ((precision == 0) || (precision > strw)) 334 391 precision = strw; … … 377 434 uint32_t flags, printf_spec_t *ps) 378 435 { 436 /* Precision not specified. */ 437 if (precision < 0) { 438 precision = 0; 439 } 440 379 441 const char *digits; 380 442 if (flags & __PRINTF_FLAG_BIGCHARS) … … 525 587 526 588 return ((int) counter); 589 } 590 591 /** Prints a special double (ie NaN, infinity) padded to width characters. */ 592 static int print_special(ieee_double_t val, int width, uint32_t flags, 593 printf_spec_t *ps) 594 { 595 assert(val.is_special); 596 597 char sign = get_sign_char(val.is_negative, flags); 598 599 const int str_len = 3; 600 const char *str; 601 602 if (flags & __PRINTF_FLAG_BIGCHARS) { 603 str = val.is_infinity ? "INF" : "NAN"; 604 } else { 605 str = val.is_infinity ? "inf" : "nan"; 606 } 607 608 int padding_len = max(0, width - ((sign ? 1 : 0) + str_len)); 609 610 int counter = 0; 611 int ret; 612 613 /* Leading padding. */ 614 if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { 615 if ((ret = print_padding(' ', padding_len, ps)) < 0) 616 return -1; 617 618 counter += ret; 619 } 620 621 if (sign) { 622 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 623 return -1; 624 625 counter += ret; 626 } 627 628 if ((ret = ps->str_write(str, str_len, ps->data)) < 0) 629 return -1; 630 631 counter += ret; 632 633 634 /* Trailing padding. */ 635 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 636 if ((ret = print_padding(' ', padding_len, ps)) < 0) 637 return -1; 638 639 counter += ret; 640 } 641 642 return counter; 643 } 644 645 /** Trims trailing zeros but leaves a single "0" intact. */ 646 static void fp_trim_trailing_zeros(char *buf, int *len, int *dec_exp) 647 { 648 /* Cut the zero off by adjusting the exponent. */ 649 while (2 <= *len && '0' == buf[*len - 1]) { 650 --*len; 651 ++*dec_exp; 652 } 653 } 654 655 /** Textually round up the last digit thereby eliminating it. */ 656 static void fp_round_up(char *buf, int *len, int *dec_exp) 657 { 658 assert(1 <= *len); 659 660 char *last_digit = &buf[*len - 1]; 661 662 int carry = ('5' <= *last_digit); 663 664 /* Cut the digit off by adjusting the exponent. */ 665 --*len; 666 ++*dec_exp; 667 --last_digit; 668 669 if (carry) { 670 /* Skip all the digits to cut off/round to zero. */ 671 while (buf <= last_digit && '9' == *last_digit) { 672 --last_digit; 673 } 674 675 /* last_digit points to the last digit to round but not '9' */ 676 if (buf <= last_digit) { 677 *last_digit += 1; 678 int new_len = last_digit - buf + 1; 679 *dec_exp += *len - new_len; 680 *len = new_len; 681 } else { 682 /* All len digits rounded to 0. */ 683 buf[0] = '1'; 684 *dec_exp += *len; 685 *len = 1; 686 } 687 } else { 688 /* The only digit was rounded to 0. */ 689 if (last_digit < buf) { 690 buf[0] = '0'; 691 *dec_exp = 0; 692 *len = 1; 693 } 694 } 695 } 696 697 698 /** Format and print the double string repressentation according 699 * to the %f specifier. 700 */ 701 static int print_double_str_fixed(double_str_t *val_str, int precision, int width, 702 uint32_t flags, printf_spec_t *ps) 703 { 704 int len = val_str->len; 705 char *buf = val_str->str; 706 int dec_exp = val_str->dec_exp; 707 708 assert(0 < len); 709 assert(0 <= precision); 710 assert(0 <= dec_exp || -dec_exp <= precision); 711 712 /* Number of integral digits to print (at least leading zero). */ 713 int int_len = max(1, len + dec_exp); 714 715 char sign = get_sign_char(val_str->neg, flags); 716 717 /* Fractional portion lengths. */ 718 int last_frac_signif_pos = max(0, -dec_exp); 719 int leading_frac_zeros = max(0, last_frac_signif_pos - len); 720 int signif_frac_figs = min(last_frac_signif_pos, len); 721 int trailing_frac_zeros = precision - last_frac_signif_pos; 722 char *buf_frac = buf + len - signif_frac_figs; 723 724 if (flags & __PRINTF_FLAG_NOFRACZEROS) { 725 trailing_frac_zeros = 0; 726 } 727 728 int frac_len = leading_frac_zeros + signif_frac_figs + trailing_frac_zeros; 729 730 bool has_decimal_pt = (0 < frac_len) || (flags & __PRINTF_FLAG_DECIMALPT); 731 732 /* Number of non-padding chars to print. */ 733 int num_len = (sign ? 1 : 0) + int_len + (has_decimal_pt ? 1 : 0) + frac_len; 734 735 int padding_len = max(0, width - num_len); 736 int ret = 0; 737 int counter = 0; 738 739 /* Leading padding and sign. */ 740 741 if (!(flags & (__PRINTF_FLAG_LEFTALIGNED | __PRINTF_FLAG_ZEROPADDED))) { 742 if ((ret = print_padding(' ', padding_len, ps)) < 0) 743 return -1; 744 745 counter += ret; 746 } 747 748 if (sign) { 749 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 750 return -1; 751 752 counter += ret; 753 } 754 755 if (flags & __PRINTF_FLAG_ZEROPADDED) { 756 if ((ret = print_padding('0', padding_len, ps)) < 0) 757 return -1; 758 759 counter += ret; 760 } 761 762 /* Print the intergral part of the buffer. */ 763 764 int buf_int_len = min(len, len + dec_exp); 765 766 if (0 < buf_int_len) { 767 if ((ret = ps->str_write(buf, buf_int_len, ps->data)) < 0) 768 return -1; 769 770 counter += ret; 771 772 /* Print trailing zeros of the integral part of the number. */ 773 if ((ret = print_padding('0', int_len - buf_int_len, ps)) < 0) 774 return -1; 775 } else { 776 /* Single leading integer 0. */ 777 char ch = '0'; 778 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 779 return -1; 780 } 781 782 counter += ret; 783 784 /* Print the decimal point and the fractional part. */ 785 if (has_decimal_pt) { 786 char ch = '.'; 787 788 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 789 return -1; 790 791 counter += ret; 792 793 /* Print leading zeros of the fractional part of the number. */ 794 if ((ret = print_padding('0', leading_frac_zeros, ps)) < 0) 795 return -1; 796 797 counter += ret; 798 799 /* Print significant digits of the fractional part of the number. */ 800 if (0 < signif_frac_figs) { 801 if ((ret = ps->str_write(buf_frac, signif_frac_figs, ps->data)) < 0) 802 return -1; 803 804 counter += ret; 805 } 806 807 /* Print trailing zeros of the fractional part of the number. */ 808 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 809 return -1; 810 811 counter += ret; 812 } 813 814 /* Trailing padding. */ 815 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 816 if ((ret = print_padding(' ', padding_len, ps)) < 0) 817 return -1; 818 819 counter += ret; 820 } 821 822 return counter; 823 } 824 825 826 /** Convert, format and print a double according to the %f specifier. 827 * 828 * @param g Double to print. 829 * @param precision Number of fractional digits to print. If 0 no 830 * decimal point will be printed unless the flag 831 * __PRINTF_FLAG_DECIMALPT is specified. 832 * @param width Minimum number of characters to display. Pads 833 * with '0' or ' ' depending on the set flags; 834 * @param flags Printf flags. 835 * @param ps Printing functions. 836 * 837 * @return The number of characters printed; negative on failure. 838 */ 839 static int print_double_fixed(double g, int precision, int width, uint32_t flags, 840 printf_spec_t *ps) 841 { 842 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 843 flags &= ~__PRINTF_FLAG_ZEROPADDED; 844 } 845 846 if (flags & __PRINTF_FLAG_DECIMALPT) { 847 flags &= ~__PRINTF_FLAG_NOFRACZEROS; 848 } 849 850 ieee_double_t val = extract_ieee_double(g); 851 852 if (val.is_special) { 853 return print_special(val, width, flags, ps); 854 } 855 856 char buf[MAX_DOUBLE_STR_BUF_SIZE]; 857 const size_t buf_size = MAX_DOUBLE_STR_BUF_SIZE; 858 double_str_t val_str; 859 860 val_str.str = buf; 861 val_str.neg = val.is_negative; 862 863 if (0 <= precision) { 864 /* 865 * Request one more digit so we can round the result. The last 866 * digit it returns may have an error of at most +/- 1. 867 */ 868 val_str.len = double_to_fixed_str(val, -1, precision + 1, buf, buf_size, 869 &val_str.dec_exp); 870 871 /* 872 * Round using the last digit to produce precision fractional digits. 873 * If less than precision+1 fractional digits were output the last 874 * digit is definitely inaccurate so also round to get rid of it. 875 */ 876 fp_round_up(buf, &val_str.len, &val_str.dec_exp); 877 878 /* Rounding could have introduced trailing zeros. */ 879 if (flags & __PRINTF_FLAG_NOFRACZEROS) { 880 fp_trim_trailing_zeros(buf, &val_str.len, &val_str.dec_exp); 881 } 882 } else { 883 /* Let the implementation figure out the proper precision. */ 884 val_str.len = double_to_short_str(val, buf, buf_size, &val_str.dec_exp); 885 886 /* Precision needed for the last significant digit. */ 887 precision = max(0, -val_str.dec_exp); 888 } 889 890 return print_double_str_fixed(&val_str, precision, width, flags, ps); 891 } 892 893 /** Prints the decimal exponent part of a %e specifier formatted number. */ 894 static int print_exponent(int exp_val, uint32_t flags, printf_spec_t *ps) 895 { 896 int counter = 0; 897 int ret; 898 899 char exp_ch = (flags & __PRINTF_FLAG_BIGCHARS) ? 'E' : 'e'; 900 901 if ((ret = ps->str_write(&exp_ch, 1, ps->data)) < 0) 902 return -1; 903 904 counter += ret; 905 906 char exp_sign = (exp_val < 0) ? '-' : '+'; 907 908 if ((ret = ps->str_write(&exp_sign, 1, ps->data)) < 0) 909 return -1; 910 911 counter += ret; 912 913 /* Print the exponent. */ 914 exp_val = abs(exp_val); 915 916 char exp_str[4] = { 0 }; 917 918 exp_str[0] = '0' + exp_val / 100; 919 exp_str[1] = '0' + (exp_val % 100) / 10 ; 920 exp_str[2] = '0' + (exp_val % 10); 921 922 int exp_len = (exp_str[0] == '0') ? 2 : 3; 923 const char *exp_str_start = &exp_str[3] - exp_len; 924 925 if ((ret = ps->str_write(exp_str_start, exp_len, ps->data)) < 0) 926 return -1; 927 928 counter += ret; 929 930 return counter; 931 } 932 933 934 /** Format and print the double string repressentation according 935 * to the %e specifier. 936 */ 937 static int print_double_str_scient(double_str_t *val_str, int precision, 938 int width, uint32_t flags, printf_spec_t *ps) 939 { 940 int len = val_str->len; 941 int dec_exp = val_str->dec_exp; 942 char *buf = val_str->str; 943 944 assert(0 < len); 945 946 char sign = get_sign_char(val_str->neg, flags); 947 bool has_decimal_pt = (0 < precision) || (flags & __PRINTF_FLAG_DECIMALPT); 948 int dec_pt_len = has_decimal_pt ? 1 : 0; 949 950 /* Fractional part lengths. */ 951 int signif_frac_figs = len - 1; 952 int trailing_frac_zeros = precision - signif_frac_figs; 953 954 if (flags & __PRINTF_FLAG_NOFRACZEROS) { 955 trailing_frac_zeros = 0; 956 } 957 958 int frac_len = signif_frac_figs + trailing_frac_zeros; 959 960 int exp_val = dec_exp + len - 1; 961 /* Account for exponent sign and 'e'; minimum 2 digits. */ 962 int exp_len = 2 + (abs(exp_val) >= 100 ? 3 : 2); 963 964 /* Number of non-padding chars to print. */ 965 int num_len = (sign ? 1 : 0) + 1 + dec_pt_len + frac_len + exp_len; 966 967 int padding_len = max(0, width - num_len); 968 int ret = 0; 969 int counter = 0; 970 971 if (!(flags & (__PRINTF_FLAG_LEFTALIGNED | __PRINTF_FLAG_ZEROPADDED))) { 972 if ((ret = print_padding(' ', padding_len, ps)) < 0) 973 return -1; 974 975 counter += ret; 976 } 977 978 if (sign) { 979 if ((ret = ps->str_write(&sign, 1, ps->data)) < 0) 980 return -1; 981 982 counter += ret; 983 } 984 985 if (flags & __PRINTF_FLAG_ZEROPADDED) { 986 if ((ret = print_padding('0', padding_len, ps)) < 0) 987 return -1; 988 989 counter += ret; 990 } 991 992 /* Single leading integer. */ 993 if ((ret = ps->str_write(buf, 1, ps->data)) < 0) 994 return -1; 995 996 counter += ret; 997 998 /* Print the decimal point and the fractional part. */ 999 if (has_decimal_pt) { 1000 char ch = '.'; 1001 1002 if ((ret = ps->str_write(&ch, 1, ps->data)) < 0) 1003 return -1; 1004 1005 counter += ret; 1006 1007 /* Print significant digits of the fractional part of the number. */ 1008 if (0 < signif_frac_figs) { 1009 if ((ret = ps->str_write(buf + 1, signif_frac_figs, ps->data)) < 0) 1010 return -1; 1011 1012 counter += ret; 1013 } 1014 1015 /* Print trailing zeros of the fractional part of the number. */ 1016 if ((ret = print_padding('0', trailing_frac_zeros, ps)) < 0) 1017 return -1; 1018 1019 counter += ret; 1020 } 1021 1022 /* Print the exponent. */ 1023 if ((ret = print_exponent(exp_val, flags, ps)) < 0) 1024 return -1; 1025 1026 counter += ret; 1027 1028 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 1029 if ((ret = print_padding(' ', padding_len, ps)) < 0) 1030 return -1; 1031 1032 counter += ret; 1033 } 1034 1035 return counter; 1036 } 1037 1038 1039 /** Convert, format and print a double according to the %e specifier. 1040 * 1041 * Note that if g is large, the output may be huge (3e100 prints 1042 * with at least 100 digits). 1043 * 1044 * %e style: [-]d.dddde+dd 1045 * left-justified: [-]d.dddde+dd[space_pad] 1046 * right-justified: [space_pad][-][zero_pad]d.dddde+dd 1047 * 1048 * @param g Double to print. 1049 * @param precision Number of fractional digits to print, ie 1050 * precision + 1 significant digits to display. If 0 no 1051 * decimal point will be printed unless the flag 1052 * __PRINTF_FLAG_DECIMALPT is specified. If negative 1053 * the shortest accurate number will be printed. 1054 * @param width Minimum number of characters to display. Pads 1055 * with '0' or ' ' depending on the set flags; 1056 * @param flags Printf flags. 1057 * @param ps Printing functions. 1058 * 1059 * @return The number of characters printed; negative on failure. 1060 */ 1061 static int print_double_scientific(double g, int precision, int width, 1062 uint32_t flags, printf_spec_t *ps) 1063 { 1064 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 1065 flags &= ~__PRINTF_FLAG_ZEROPADDED; 1066 } 1067 1068 ieee_double_t val = extract_ieee_double(g); 1069 1070 if (val.is_special) { 1071 return print_special(val, width, flags, ps); 1072 } 1073 1074 char buf[MAX_DOUBLE_STR_BUF_SIZE]; 1075 const size_t buf_size = MAX_DOUBLE_STR_BUF_SIZE; 1076 double_str_t val_str; 1077 1078 val_str.str = buf; 1079 val_str.neg = val.is_negative; 1080 1081 if (0 <= precision) { 1082 /* 1083 * Request one more digit (in addition to the leading integer) 1084 * so we can round the result. The last digit it returns may 1085 * have an error of at most +/- 1. 1086 */ 1087 val_str.len = double_to_fixed_str(val, precision + 2, -1, buf, buf_size, 1088 &val_str.dec_exp); 1089 1090 /* 1091 * Round the extra digit to produce precision+1 significant digits. 1092 * If less than precision+2 significant digits were returned the last 1093 * digit is definitely inaccurate so also round to get rid of it. 1094 */ 1095 fp_round_up(buf, &val_str.len, &val_str.dec_exp); 1096 1097 /* Rounding could have introduced trailing zeros. */ 1098 if (flags & __PRINTF_FLAG_NOFRACZEROS) { 1099 fp_trim_trailing_zeros(buf, &val_str.len, &val_str.dec_exp); 1100 } 1101 } else { 1102 /* Let the implementation figure out the proper precision. */ 1103 val_str.len = double_to_short_str(val, buf, buf_size, &val_str.dec_exp); 1104 1105 /* Use all produced digits. */ 1106 precision = val_str.len - 1; 1107 } 1108 1109 return print_double_str_scient(&val_str, precision, width, flags, ps); 1110 } 1111 1112 1113 /** Convert, format and print a double according to the %g specifier. 1114 * 1115 * %g style chooses between %f and %e. 1116 * 1117 * @param g Double to print. 1118 * @param precision Number of significant digits to display; excluding 1119 * any leading zeros from this count. If negative 1120 * the shortest accurate number will be printed. 1121 * @param width Minimum number of characters to display. Pads 1122 * with '0' or ' ' depending on the set flags; 1123 * @param flags Printf flags. 1124 * @param ps Printing functions. 1125 * 1126 * @return The number of characters printed; negative on failure. 1127 */ 1128 static int print_double_generic(double g, int precision, int width, 1129 uint32_t flags, printf_spec_t *ps) 1130 { 1131 ieee_double_t val = extract_ieee_double(g); 1132 1133 if (val.is_special) { 1134 return print_special(val, width, flags, ps); 1135 } 1136 1137 char buf[MAX_DOUBLE_STR_BUF_SIZE]; 1138 const size_t buf_size = MAX_DOUBLE_STR_BUF_SIZE; 1139 int dec_exp; 1140 int len; 1141 1142 /* Honor the user requested number of significant digits. */ 1143 if (0 <= precision) { 1144 /* 1145 * Do a quick and dirty conversion of a single digit to determine 1146 * the decimal exponent. 1147 */ 1148 len = double_to_fixed_str(val, 1, -1, buf, buf_size, &dec_exp); 1149 assert(0 < len); 1150 1151 precision = max(1, precision); 1152 1153 if (-4 <= dec_exp && dec_exp < precision) { 1154 precision = precision - (dec_exp + 1); 1155 return print_double_fixed(g, precision, width, 1156 flags | __PRINTF_FLAG_NOFRACZEROS, ps); 1157 } else { 1158 --precision; 1159 return print_double_scientific(g, precision, width, 1160 flags | __PRINTF_FLAG_NOFRACZEROS, ps); 1161 } 1162 } else { 1163 /* Convert to get the decimal exponent and digit count.*/ 1164 len = double_to_short_str(val, buf, buf_size, &dec_exp); 1165 assert(0 < len); 1166 1167 if (flags & __PRINTF_FLAG_LEFTALIGNED) { 1168 flags &= ~__PRINTF_FLAG_ZEROPADDED; 1169 } 1170 1171 double_str_t val_str; 1172 val_str.str = buf; 1173 val_str.len = len; 1174 val_str.neg = val.is_negative; 1175 val_str.dec_exp = dec_exp; 1176 1177 int first_digit_pos = len + dec_exp; 1178 int last_digit_pos = dec_exp; 1179 1180 /* The whole number (15 digits max) fits between dec places 15 .. -6 */ 1181 if (len <= 15 && -6 <= last_digit_pos && first_digit_pos <= 15) { 1182 /* Precision needed for the last significant digit. */ 1183 precision = max(0, -val_str.dec_exp); 1184 return print_double_str_fixed(&val_str, precision, width, flags, ps); 1185 } else { 1186 /* Use all produced digits. */ 1187 precision = val_str.len - 1; 1188 return print_double_str_scient(&val_str, precision, width, flags, ps); 1189 } 1190 } 1191 } 1192 1193 1194 /** Convert, format and print a double according to the specifier. 1195 * 1196 * Depending on the specifier it prints the double using the styles 1197 * %g, %f or %e by means of print_double_generic(), print_double_fixed(), 1198 * print_double_scientific(). 1199 * 1200 * @param g Double to print. 1201 * @param spec Specifier of the style to print in; one of: 'g','G','f','F', 1202 * 'e','E'. 1203 * @param precision Number of fractional digits to display. If negative 1204 * the shortest accurate number will be printed for style %g; 1205 * negative precision defaults to 6 for styles %f, %e. 1206 * @param width Minimum number of characters to display. Pads 1207 * with '0' or ' ' depending on the set flags; 1208 * @param flags Printf flags. 1209 * @param ps Printing functions. 1210 * 1211 * @return The number of characters printed; negative on failure. 1212 */ 1213 static int print_double(double g, char spec, int precision, int width, 1214 uint32_t flags, printf_spec_t *ps) 1215 { 1216 switch (spec) { 1217 case 'F': 1218 flags |= __PRINTF_FLAG_BIGCHARS; 1219 /* Fall through.*/ 1220 case 'f': 1221 precision = (precision < 0) ? 6 : precision; 1222 return print_double_fixed(g, precision, width, flags, ps); 1223 1224 case 'E': 1225 flags |= __PRINTF_FLAG_BIGCHARS; 1226 /* Fall through.*/ 1227 case 'e': 1228 precision = (precision < 0) ? 6 : precision; 1229 return print_double_scientific(g, precision, width, flags, ps); 1230 1231 case 'G': 1232 flags |= __PRINTF_FLAG_BIGCHARS; 1233 /* Fall through.*/ 1234 case 'g': 1235 return print_double_generic(g, precision, width, flags, ps); 1236 1237 default: 1238 assert(false); 1239 return -1; 1240 } 527 1241 } 528 1242 … … 656 1370 case '#': 657 1371 flags |= __PRINTF_FLAG_PREFIX; 1372 flags |= __PRINTF_FLAG_DECIMALPT; 658 1373 break; 659 1374 case '-': … … 701 1416 702 1417 /* Precision and '*' operator */ 703 int precision = 0;1418 int precision = -1; 704 1419 if (uc == '.') { 705 1420 i = nxt; 706 1421 uc = str_decode(fmt, &nxt, STR_NO_LIMIT); 707 1422 if (isdigit(uc)) { 1423 precision = 0; 708 1424 while (true) { 709 1425 precision *= 10; … … 723 1439 precision = (int) va_arg(ap, int); 724 1440 if (precision < 0) { 725 /* Ignore negative precision */726 precision = 0;1441 /* Ignore negative precision - use default instead */ 1442 precision = -1; 727 1443 } 728 1444 } … … 774 1490 */ 775 1491 case 's': 1492 precision = max(0, precision); 1493 776 1494 if (qualifier == PrintfQualifierLong) 777 1495 retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps); … … 797 1515 goto out; 798 1516 }; 1517 1518 counter += retval; 1519 j = nxt; 1520 goto next_char; 1521 1522 /* 1523 * Floating point values 1524 */ 1525 case 'G': 1526 case 'g': 1527 case 'F': 1528 case 'f': 1529 case 'E': 1530 case 'e': 1531 retval = print_double(va_arg(ap, double), uc, precision, 1532 width, flags, ps); 1533 1534 if (retval < 0) { 1535 counter = -counter; 1536 goto out; 1537 } 799 1538 800 1539 counter += retval; -
uspace/lib/c/include/macros.h
r508fff8 rf220e25 38 38 #define min(a, b) ((a) < (b) ? (a) : (b)) 39 39 #define max(a, b) ((a) > (b) ? (a) : (b)) 40 #define abs(a) ((a) >= 0 ? (a) : (-a)) 41 40 42 41 43 #define KiB2SIZE(kb) ((kb) << 10) -
uspace/lib/clui/tinput.c
r508fff8 rf220e25 104 104 static void tinput_display_tail(tinput_t *ti, size_t start, size_t pad) 105 105 { 106 wchar_t dbuf[INPUT_MAX_SIZE + 1]; 106 wchar_t *dbuf = malloc((INPUT_MAX_SIZE + 1) * sizeof(wchar_t)); 107 if (!dbuf) 108 return; 107 109 108 110 size_t sa; … … 146 148 147 149 console_flush(ti->console); 150 151 free(dbuf); 148 152 } 149 153
Note:
See TracChangeset
for help on using the changeset viewer.