Sending my patch. Hopefully fixes trac.helenos.org/ticket/221
Adam
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [email protected]
# target_branch: bzr://bzr.helenos.org/mainline/
# testament_sha1: f0d86f7c0c9aa3b0f2d4072280f20cd7361ae428
# timestamp: 2012-04-07 17:03:40 +0200
# base_revision_id: jiri@wiwaxia-20120405224251-l7sx79xi2488v3ko
#
# Begin patch
=== modified file 'uspace/app/tester/print/print2.c'
--- uspace/app/tester/print/print2.c 2011-08-23 17:44:33 +0000
+++ uspace/app/tester/print/print2.c 2012-04-07 15:00:54 +0000
@@ -51,6 +51,10 @@
TPRINTF("Testing printf(\"%%#x %%5.3#x %%-5.3#x %%3.5#x %%-3.5#x\", 17, 18, 19, 20, 21):\n");
TPRINTF("Expected output: [0x11] [0x012] [0x013] [0x00014] [0x00015]\n");
TPRINTF("Real output: [%#x] [%#5.3x] [%#-5.3x] [%#3.5x] [%#-3.5x]\n\n", 17, 18, 19, 20, 21);
+
+ TPRINTF("Testing printf(\"%%f %%0.2f\", 3.1415,3.1415,-3.1415,123.4567):\n");
+ TPRINTF("Expected output: [3.1] [3.14] [-3.141] [00123.45670] \n");
+ TPRINTF("Real output: [%f] [%0.2f] [%0.3f] [%5.5f] \n\n", 3.1415,3.1415,-3.1415,123.4567);
return NULL;
}
=== modified file 'uspace/lib/c/generic/io/printf_core.c'
--- uspace/lib/c/generic/io/printf_core.c 2011-08-23 17:44:33 +0000
+++ uspace/lib/c/generic/io/printf_core.c 2012-04-07 15:00:54 +0000
@@ -92,12 +92,14 @@
res; \
})
+
/** Enumeration of possible arguments types.
*/
typedef enum {
PrintfQualifierByte = 0,
PrintfQualifierShort,
PrintfQualifierInt,
+ PrintfQualifierFloat,
PrintfQualifierLong,
PrintfQualifierLongLong,
PrintfQualifierPointer,
@@ -360,7 +362,7 @@
return ((int) counter);
}
-/** Print a number in a given base.
+/** Print an integer in a given base.
*
* Print significant digits of a number in given base.
*
@@ -526,6 +528,74 @@
return ((int) counter);
}
+
+/** Print a float in base 10.
+ *
+ * Print significant digits of a number in given base.
+ *
+ * @param num Number to print.
+ * @param width Width modifier.
+ * @param precision Precision modifier.
+ * @param base Base to print the number in (must be between 2 and 16).
+ * @param flags Flags that modify the way the number is printed.
+ *
+ * @return Number of characters printed.
+ *
+ */
+static int print_float(double num, int width, int precision,
+ uint32_t flags, printf_spec_t *ps)
+{
+ int base;
+ base=10;
+ int counter; counter=0;
+ int result;
+
+ /*handle negative numbers*/
+ uint32_t flags_fraction=flags;
+ if(num <0){
+ (flags) |= __PRINTF_FLAG_NEGATIVE;
+ num*=-1;
+ }
+
+ /*get the whole part*/
+ uint64_t whole = num;
+
+ /*get fraction*/
+ uint64_t fraction;
+ {
+ num-=whole;
+ while(precision>1){
+ num*=10;
+ precision--;
+ }
+ num*=10;
+ fraction=num;
+ }
+
+ /*print the whole part*/
+ result = print_number(whole,0,width,base,flags,ps);
+ if(result<0){
+ return result;
+ }
+ counter+=result;
+
+ /*print the dot*/
+ result = print_char('.',1,flags,ps);
+ if(result<0){
+ return result;
+ }
+ counter++;
+
+ /*print the rest (witout negative flag)*/
+ result = print_number(fraction,0,0,base,flags_fraction,ps);
+ if(result<0){
+ return result;
+ }
+ counter+=result;
+
+ return ((int) counter);
+}
+
/** Print formatted string.
*
* Print string formatted according to the fmt parameter and variadic arguments.
@@ -601,7 +671,9 @@
*
* - d, i Print signed decimal number. There is no difference between d
* and i conversion.
- *
+ *
+ * - f Print signed decimal float.
+ *
* - u Print unsigned decimal number.
*
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is
@@ -756,6 +828,10 @@
qualifier = PrintfQualifierLongLong;
}
break;
+ case 'f':
+ /* Float */
+ qualifier = PrintfQualifierFloat;
+ break;
case 'z':
qualifier = PrintfQualifierSize;
i = nxt;
@@ -821,6 +897,9 @@
break;
case 'd':
case 'i':
+ /* necessary to case 'f' again, so it won't fall through
+ * and have signed printing in sub routines */
+ case 'f':
flags |= __PRINTF_FLAG_SIGNED;
case 'u':
break;
@@ -880,14 +959,28 @@
size = sizeof(size_t);
number = (uint64_t) va_arg(ap, size_t);
break;
+ /*Float is a known qualifier, but will be a special case*/
+ case PrintfQualifierFloat:
+ break;
default:
/* Unknown qualifier */
counter = -counter;
goto out;
}
- if ((retval = print_number(number, width, precision,
- base, flags, ps)) < 0) {
+ /*Either float or integer*/
+ if(PrintfQualifierFloat == qualifier) {
+ double fnumber;
+ size = sizeof(float);
+ fnumber = (float) va_arg(ap, double);
+ retval = print_float(fnumber, width, precision,
+ flags, ps);
+ }else{
+ retval = print_number(number, width, precision,
+ base, flags, ps);
+ }
+
+ if (retval < 0) {
counter = -counter;
goto out;
}
# Begin bundle
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
_______________________________________________
HelenOS-devel mailing list
[email protected]
http://lists.modry.cz/cgi-bin/listinfo/helenos-devel