|
From: <sv...@va...> - 2005-08-25 21:20:27
|
Author: sewardj
Date: 2005-08-25 22:20:18 +0100 (Thu, 25 Aug 2005)
New Revision: 1361
Log:
vex_printf/sprintf hackery.
Modified:
trunk/priv/main/vex_util.c
trunk/priv/main/vex_util.h
Modified: trunk/priv/main/vex_util.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/main/vex_util.c 2005-08-24 17:50:59 UTC (rev 1360)
+++ trunk/priv/main/vex_util.c 2005-08-25 21:20:18 UTC (rev 1361)
@@ -179,26 +179,6 @@
New code for vex_util.c should go above this point. */
#include <stdarg.h>
=20
-/* ---------------------------------------------------------------------
- printf implementation. The key function, vg_vprintf(), emits chars=20
- into a caller-supplied function. Distantly derived from:
-
- vprintf replacement for Checker.
- Copyright 1993, 1994, 1995 Tristan Gingold
- Written September 1993 Tristan Gingold
- Tristan Gingold, 8 rue Parmentier, F-91120 PALAISEAU, FRANCE
-
- (Checker itself was GPL'd.)
- ------------------------------------------------------------------ */
-
-static HChar vex_toupper ( HChar c )
-{
- if (c >=3D 'a' && c <=3D 'z')
- return toHChar(c + ('A' - 'a'));
- else
- return c;
-}
-
static Int vex_strlen ( const HChar* str )
{
Int i =3D 0;
@@ -218,252 +198,211 @@
}
}
=20
-/* Some flags. */
-#define VG_MSG_SIGNED 1 /* The value is signed. */
-#define VG_MSG_ZJUSTIFY 2 /* Must justify with '0'. */
-#define VG_MSG_LJUSTIFY 4 /* Must justify on the left. */
-#define VG_MSG_PAREN 8 /* Parenthesize if present (for %y) */
-#define VG_MSG_COMMA 16 /* Add commas to numbers (for %d, %u) */
=20
-/* Copy a string into the buffer. */
-static UInt
-myvprintf_str ( void(*send)(HChar), Int flags, Int width, HChar* str,=20
- Bool capitalise )
+/* Convert N0 into ascii in BUF, which is assumed to be big enough (at
+ least 67 bytes long). Observe BASE, SYNED and HEXCAPS. */
+static
+void convert_int ( /*OUT*/HChar* buf, Long n0,=20
+ Int base, Bool syned, Bool hexcaps )
{
-# define MAYBE_TOUPPER(ch) toHChar(capitalise ? vex_toupper(ch) : (ch))
- UInt ret =3D 0;
- Int i, extra;
- Int len =3D vex_strlen(str);
+ ULong u0;
+ HChar c;
+ Bool minus =3D False;
+ Int i, j, bufi =3D 0;
+ buf[bufi] =3D 0;
=20
- if (width =3D=3D 0) {
- ret +=3D len;
- for (i =3D 0; i < len; i++)
- send(MAYBE_TOUPPER(str[i]));
- return ret;
+ if (syned) {
+ if (n0 < 0) {
+ minus =3D True;
+ u0 =3D (ULong)(-n0);
+ } else {
+ u0 =3D (ULong)(n0);
+ }
+ } else {
+ u0 =3D (ULong)n0;
}
=20
- if (len > width) {
- ret +=3D width;
- for (i =3D 0; i < width; i++)
- send(MAYBE_TOUPPER(str[i]));
- return ret;
+ while (1) {
+ buf[bufi++] =3D '0' + (HChar)(u0 % base);
+ u0 /=3D base;
+ if (u0 =3D=3D 0) break;
}
+ if (minus)
+ buf[bufi++] =3D '-';
=20
- extra =3D width - len;
- if (flags & VG_MSG_LJUSTIFY) {
- ret +=3D extra;
- for (i =3D 0; i < extra; i++)
- send(' ');
- }
- ret +=3D len;
- for (i =3D 0; i < len; i++)
- send(MAYBE_TOUPPER(str[i]));
- if (!(flags & VG_MSG_LJUSTIFY)) {
- ret +=3D extra;
- for (i =3D 0; i < extra; i++)
- send(' ');
- }
+ buf[bufi] =3D 0;
+ for (i =3D 0; i < bufi; i++)
+ if (buf[i] > '9')=20
+ buf[i] +=3D ((hexcaps ? 'A' : 'a') - '9' - 1);
=20
-# undef MAYBE_TOUPPER
-
- return ret;
+ i =3D 0;
+ j =3D bufi-1;
+ while (i <=3D j) {
+ c =3D buf[i];
+ buf[i] =3D buf[j];
+ buf[j] =3D c;
+ i++;
+ j--;
+ }
}
=20
-/* Write P into the buffer according to these args:
- * If SIGN is true, p is a signed.
- * BASE is the base.
- * If WITH_ZERO is true, '0' must be added.
- * WIDTH is the width of the field.
- */
-static UInt
-myvprintf_int64 ( void(*send)(HChar), Int flags, Int base, Int width, UL=
ong p)
+
+/* A half-arsed and buggy, but good-enough, implementation of
+ printf. */
+static
+UInt vprintf_wrk ( void(*sink)(HChar),
+ HChar* format,
+ va_list ap )
{
- HChar buf[40];
- Int ind =3D 0;
- Int i, nc =3D 0;
- Bool neg =3D False;
- HChar *digits =3D "0123456789ABCDEF";
- UInt ret =3D 0;
+# define PUT(_ch) \
+ do { sink(_ch); nout++; } \
+ while (0)
=20
- if (base < 2 || base > 16)
- return ret;
-=20
- if ((flags & VG_MSG_SIGNED) && (Long)p < 0) {
- p =3D - (Long)p;
- neg =3D True;
- }
+# define PAD(_n) \
+ do { Int _qq =3D (_n); for (; _qq > 0; _qq--) PUT(padchar); } \
+ while (0)
=20
- if (p =3D=3D 0)
- buf[ind++] =3D '0';
- else {
- while (p > 0) {
- if ((flags & VG_MSG_COMMA) && 10 =3D=3D base &&
- 0 =3D=3D (ind-nc) % 3 && 0 !=3D ind)=20
- {
- buf[ind++] =3D ',';
- nc++;
- }
- buf[ind++] =3D digits[p % base];
- p /=3D base;
- }
- }
+# define PUTSTR(_str) \
+ do { HChar* _qq =3D _str; for (; *_qq; _qq++) PUT(*_qq); } \
+ while (0)
=20
- if (neg)
- buf[ind++] =3D '-';
+ HChar* saved_format;
+ Bool longlong, ljustify;
+ HChar padchar;
+ Int fwidth, nout, len1, len2, len3;
+ HChar intbuf[100]; /* big enough for a 64-bit # in base 2 */
=20
- if (width > 0 && !(flags & VG_MSG_LJUSTIFY)) {
- for(; ind < width; ind++) {
- vassert(ind < 39);
- buf[ind] =3D toHChar((flags & VG_MSG_ZJUSTIFY) ? '0': ' ');
- }
- }
+ nout =3D 0;
+ while (1) {
=20
- /* Reverse copy to buffer. */
- ret +=3D ind;
- for (i =3D ind -1; i >=3D 0; i--) {
- send(buf[i]);
- }
- if (width > 0 && (flags & VG_MSG_LJUSTIFY)) {
- for(; ind < width; ind++) {
- ret++;
- send(' '); // Never pad with zeroes on RHS -- changes the valu=
e!
+ if (!format)
+ break;
+ if (*format =3D=3D 0)=20
+ break;
+
+ if (*format !=3D '%') {
+ PUT(*format);=20
+ format++;
+ continue;
}
- }
- return ret;
-}
=20
+ saved_format =3D format;
+ longlong =3D False;
+ ljustify =3D False;
+ padchar =3D ' ';
+ fwidth =3D 0;
+ format++;
=20
-/* A simple vprintf(). */
-static=20
-UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list varg=
s )
-{
- UInt ret =3D 0;
- int i;
- int flags;
- int width;
- Bool is_long;
-
- /* We assume that vargs has already been initialised by the=20
- caller, using va_start, and that the caller will similarly
- clean up with va_end.
- */
-
- for (i =3D 0; format[i] !=3D 0; i++) {
- if (format[i] !=3D '%') {
- send(format[i]);
- ret++;
- continue;
+ if (*format =3D=3D '-') {
+ format++;
+ ljustify =3D True;
}
- i++;
- /* A '%' has been found. Ignore a trailing %. */
- if (format[i] =3D=3D 0)
- break;
- if (format[i] =3D=3D '%') {
- /* `%%' is replaced by `%'. */
- send('%');
- ret++;
- continue;
+ if (*format =3D=3D '0') {
+ format++;
+ padchar =3D '0';
}
- flags =3D 0;
- is_long =3D False;
- width =3D 0; /* length of the field. */
- if (format[i] =3D=3D '(') {
- flags |=3D VG_MSG_PAREN;
- i++;
+ while (*format >=3D '0' && *format <=3D '9') {
+ fwidth =3D fwidth * 10 + (*format - '0');
+ format++;
}
- /* If ',' follows '%', commas will be inserted. */
- if (format[i] =3D=3D ',') {
- flags |=3D VG_MSG_COMMA;
- i++;
+ if (*format =3D=3D 'l') {
+ format++;
+ if (*format =3D=3D 'l') {
+ format++;
+ longlong =3D True;
+ }
}
- /* If '-' follows '%', justify on the left. */
- if (format[i] =3D=3D '-') {
- flags |=3D VG_MSG_LJUSTIFY;
- i++;
- }
- /* If '0' follows '%', pads will be inserted. */
- if (format[i] =3D=3D '0') {
- flags |=3D VG_MSG_ZJUSTIFY;
- i++;
- }
- /* Compute the field length. */
- while (format[i] >=3D '0' && format[i] <=3D '9') {
- width *=3D 10;
- width +=3D format[i++] - '0';
- }
- while (format[i] =3D=3D 'l') {
- i++;
- is_long =3D True;
- }
=20
- switch (format[i]) {
- case 'd': /* %d */
- flags |=3D VG_MSG_SIGNED;
- if (is_long)
- ret +=3D myvprintf_int64(send, flags, 10, width,=20
- (ULong)(va_arg (vargs, Long)));
- else
- ret +=3D myvprintf_int64(send, flags, 10, width,=20
- (ULong)(va_arg (vargs, Int)));
+ switch (*format) {
+ case 's': {
+ HChar* str =3D va_arg(ap, HChar*);
+ if (str =3D=3D NULL)
+ str =3D "(null)";
+ len1 =3D len3 =3D 0;
+ len2 =3D vex_strlen(str);
+ if (fwidth > len2) { len1 =3D ljustify ? fwidth-len2 : 0;
+ len3 =3D ljustify ? 0 : fwidth-len2; }
+ PAD(len1); PUTSTR(str); PAD(len3);
break;
- case 'u': /* %u */
- if (is_long)
- ret +=3D myvprintf_int64(send, flags, 10, width,=20
- (ULong)(va_arg (vargs, ULong)));
- else
- ret +=3D myvprintf_int64(send, flags, 10, width,=20
- (ULong)(va_arg (vargs, UInt)));
+ }
+ case 'c': {
+ HChar c =3D (HChar)va_arg(ap, int);
+ HChar str[2];
+ str[0] =3D c;
+ str[1] =3D 0;
+ len1 =3D len3 =3D 0;
+ len2 =3D vex_strlen(str);
+ if (fwidth > len2) { len1 =3D ljustify ? fwidth-len2 : 0;
+ len3 =3D ljustify ? 0 : fwidth-len2; }
+ PAD(len1); PUTSTR(str); PAD(len3);
break;
- case 'p': /* %p */
- ret +=3D 2;
- send('0');
- send('x');
- ret +=3D myvprintf_int64(send, flags, 16, width,=20
- (ULong)((HWord)va_arg (vargs, void *)=
));
+ }
+ case 'd': {
+ Long l;
+ if (longlong) {
+ l =3D va_arg(ap, Long);
+ } else {
+ l =3D (Long)va_arg(ap, Int);
+ }
+ convert_int(intbuf, l, 10/*base*/, True/*signed*/,
+ False/*irrelevant*/);
+ len1 =3D len3 =3D 0;
+ len2 =3D vex_strlen(intbuf);
+ if (fwidth > len2) { len1 =3D ljustify ? fwidth-len2 : 0;
+ len3 =3D ljustify ? 0 : fwidth-len2; }
+ PAD(len1); PUTSTR(intbuf); PAD(len3);
break;
- case 'x': /* %x */
- if (is_long)
- ret +=3D myvprintf_int64(send, flags, 16, width,=20
- (ULong)(va_arg (vargs, ULong)));
- else
- ret +=3D myvprintf_int64(send, flags, 16, width,=20
- (ULong)(va_arg (vargs, UInt)));
- break;
- case 'c': /* %c */
- ret++;
- send(toHChar(va_arg (vargs, int)));
- break;
- case 's': case 'S': { /* %s */
- char *str =3D va_arg (vargs, char *);
- if (str =3D=3D (char*) 0) str =3D "(null)";
- ret +=3D myvprintf_str(send, flags, width, str,=20
- toBool(format[i]=3D=3D'S'));
- break;
}
-# if 0
- case 'y': { /* %y - print symbol */
- Char buf[100];
- Char *cp =3D buf;
- Addr a =3D va_arg(vargs, Addr);
-
- if (flags & VG_MSG_PAREN)
- *cp++ =3D '(';
- if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) {
- if (flags & VG_MSG_PAREN) {
- cp +=3D VG_(strlen)(cp);
- *cp++ =3D ')';
- *cp =3D '\0';
- }
- ret +=3D myvprintf_str(send, flags, width, buf, 0);
+ case 'u':=20
+ case 'x':=20
+ case 'X': {
+ Int base =3D *format =3D=3D 'u' ? 10 : 16;
+ Bool hexcaps =3D True; /* *format =3D=3D 'X'; */
+ ULong l;
+ if (longlong) {
+ l =3D va_arg(ap, ULong);
+ } else {
+ l =3D (ULong)va_arg(ap, UInt);
}
+ convert_int(intbuf, l, base, False/*unsigned*/, hexcaps);
+ len1 =3D len3 =3D 0;
+ len2 =3D vex_strlen(intbuf);
+ if (fwidth > len2) { len1 =3D ljustify ? fwidth-len2 : 0;
+ len3 =3D ljustify ? 0 : fwidth-len2; }
+ PAD(len1); PUTSTR(intbuf); PAD(len3);
break;
}
-# endif
+ case 'p':=20
+ case 'P': {
+ Bool hexcaps =3D *format =3D=3D 'P';
+ ULong l =3D Ptr_to_ULong( va_arg(ap, void*) );
+ convert_int(intbuf, l, 16/*base*/, False/*unsigned*/, hexcap=
s);
+ len1 =3D len3 =3D 0;
+ len2 =3D vex_strlen(intbuf)+2;
+ if (fwidth > len2) { len1 =3D ljustify ? fwidth-len2 : 0;
+ len3 =3D ljustify ? 0 : fwidth-len2; }
+ PAD(len1); PUT('0'); PUT('x'); PUTSTR(intbuf); PAD(len3);
+ break;
+ }
default:
+ /* no idea what it is. Print the format literally and
+ move on. */
+ while (saved_format <=3D format) {
+ PUT(*saved_format);
+ saved_format++;
+ }
break;
}
+
+ format++;
+
}
- return ret;
+
+ return nout;
+
+# undef PUT
+# undef PAD
+# undef PUTSTR
}
=20
=20
@@ -476,16 +415,17 @@
=20
static void add_to_myprintf_buf ( HChar c )
{
- if (c =3D=3D '\n' || n_myprintf_buf >=3D 1000-10 /*paranoia*/ ) {
+ Bool emit =3D c =3D=3D '\n' || n_myprintf_buf >=3D 1000-10 /*paranoia=
*/;
+ myprintf_buf[n_myprintf_buf++] =3D c;
+ myprintf_buf[n_myprintf_buf] =3D 0;
+ if (emit) {
(*vex_log_bytes)( myprintf_buf, vex_strlen(myprintf_buf) );
n_myprintf_buf =3D 0;
- myprintf_buf[n_myprintf_buf] =3D 0; =20
+ myprintf_buf[n_myprintf_buf] =3D 0;
}
- myprintf_buf[n_myprintf_buf++] =3D c;
- myprintf_buf[n_myprintf_buf] =3D 0;
}
=20
-UInt vex_printf ( const char *format, ... )
+UInt vex_printf ( HChar* format, ... )
{
UInt ret;
va_list vargs;
@@ -514,7 +454,7 @@
*vg_sprintf_ptr++ =3D c;
}
=20
-UInt vex_sprintf ( HChar* buf, const HChar *format, ... )
+UInt vex_sprintf ( HChar* buf, HChar *format, ... )
{
Int ret;
va_list vargs;
Modified: trunk/priv/main/vex_util.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/main/vex_util.h 2005-08-24 17:50:59 UTC (rev 1360)
+++ trunk/priv/main/vex_util.h 2005-08-25 21:20:18 UTC (rev 1361)
@@ -75,10 +75,10 @@
/* Printing */
=20
__attribute__ ((format (printf, 1, 2)))
-extern UInt vex_printf ( const HChar *format, ... );
+extern UInt vex_printf ( HChar *format, ... );
=20
__attribute__ ((format (printf, 2, 3)))
-extern UInt vex_sprintf ( HChar* buf, const HChar *format, ... );
+extern UInt vex_sprintf ( HChar* buf, HChar *format, ... );
=20
=20
/* String ops */
|