%a in vfprintf

Grzegorz Błach grzela at seculture.com
Sat Mar 24 04:07:14 PDT 2007


Dnia 23-03-2007, Pt o godzinie 16:41 +0100, Simon 'corecode' Schubert
napisał(a):
> On 23.03.2007, at 15:36, Grzegorz BÅ‚ach wrote:
> > but HEXFLOAT is never defined.
> 
> I think Joerg added this, but shielded it off with the define.
> 
> > Can anyone check if HEXFLOAT is defined, "%a" argument
> > works correctly (and make this the default)?
> 
> Yes, please check if it works and doesn't break other behavior in 
> printf.  If your results are successful, I'll remove the conditional.
> 
> cheers
>    simon
> 

I tryed work on %a printf argument, and I don't know where is __hdtoa
function. This function is invoked in vfwprintf.c and it works,
but in vforintf.c invoking it fails.

Also I observed that DFly's vfwprintf.c is very similar to Freebsd 5's
vfprintf.c.

So my questions:
1) what I must do to use __hdtoa in vfprintf.c.
2) what is difference between vfwprintf and vfprintf
	(what 'wide chars' mean).
3) is posibile to make vfprint a wrapper to vfwprintf.

Unfinished patch is attached.

diff -uNr src/lib/libc/stdio/vfprintf.c src+/lib/libc/stdio/vfprintf.c
--- src/lib/libc/stdio/vfprintf.c	2006-07-05 17:04:54.000000000 +0200
+++ src+/lib/libc/stdio/vfprintf.c	2007-03-24 12:41:26.000000000 +0100
@@ -805,10 +807,18 @@
 			base = 10;
 			goto number;
 #ifndef NO_FLOATING_POINT
-#ifdef HEXFLOAT
 		case 'a':
+			ox[1] = 'x';
+			xdigs = "0123456789abcdef";
+			goto hexfloat;
 		case 'A':
-#endif
+			ox[1] = 'X';
+			xdigs = "0123456789ABCDEF";
+hexfloat:
+			if (prec >= 0)
+				prec++;
+    			if (expt == INT_MAX)
+				ox[1] = '\0';
 		case 'e':
 		case 'E':
 			/*
@@ -826,7 +836,7 @@
 		case 'G':
 			if (prec == 0)
 				prec = 1;
-fp_begin:		if (prec == -1)
+fp_begin:		if (prec < 0)
 				prec = DEFPREC;
 			if (flags & LONGDBL)
 				/* XXX this loses precision. */
@@ -857,15 +867,23 @@
 				free(dtoaresult);
 				dtoaresult = NULL;
 			}
-			cp = cvt(_double, prec, flags, &softsign,
-				&expt, ch, &ndig, &dtoaresult);
+    			if(ch == 'a' || ch == 'A')
+                            cp = __hdtoa(_double, xdigs, prec,
+				        &expt, &softsign, &dtoaresult);
+        		else cp = cvt(_double, prec, flags, &softsign,
+					&expt, ch, &ndig, &dtoaresult);
 			if (ch == 'g' || ch == 'G') {
 				if (expt <= -4 || expt > prec)
 					ch = (ch == 'g') ? 'e' : 'E';
 				else
 					ch = 'g';
 			}
-			if (ch == 'e' || ch == 'E') {
+    			if (ch == 'a' || ch == 'A') {
+                            	expsize = exponent(expstr, expt - 1, ch == 'a' ? 'p' : 'P');
+				size = expsize + prec;
+				if (prec > 1 || flags & ALT)
+					++size;
+                        } else if (ch == 'e' || ch == 'E') {
 				--expt;
 				expsize = exponent(expstr, expt, ch);
 				size = expsize + ndig;
@@ -1581,8 +1599,15 @@
 		for (; t < expbuf + MAXEXPDIG; *p++ = *t++);
 	}
 	else {
-		*p++ = '0';
-		*p++ = to_char(expo);
+		/*
+		 * Exponents for decimal floating point conversions
+		 * (%[eEgG]) must be at least two characters long,
+		 * whereas exponents for hexadecimal conversions can
+		 * be only one character long.
+		 */
+		if (fmtch == 'e' || fmtch == 'E')
+			*p++ = '0';
+            	*p++ = to_char(expo);
 	}
 	return (p - p0);
 }
____________________________________________________________________________
. com = 9,90, .pl = 29,90 
www.nazwa.pl



More information about the Kernel mailing list