ftmemsim-valgrind/none/tests/unit_debuglog.c
Florian Krohm f7c5c06c5d Add limited support for printing floating point numbers to
VG_(debugLog_vprintf). 
Remove function VG_(percentify) and fix up its call sites (part of
fixing BZ #337869.
Allow the width in a format specification to be '*', i.e. the width is
given as an additional function argument.

The limitations for printing floating point numbers are:
(1) %f is the only supported format. Width and precision can be
    specified.
(2) Funny numbers (NaN and such) are not supported.
(3) Floating point numbers need to be benign in the sense that their
    integral part fits into an ULong.
This is good enough for our purposes.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14806
2014-12-12 19:32:10 +00:00

149 lines
3.4 KiB
C

/* Test %f format specifier */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pub_core_basics.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
#undef vg_assert
#define vg_assert(e) assert(e)
#undef vg_assert2
#define vg_assert2(e, fmt, args...) assert(e)
#include "coregrind/m_debuglog.c"
void run(const char *format, ...)
{
int n, num_stars, i1, i2;
const char *p;
printf_buf buf;
va_list vargs;
// Count number of '*' in format
num_stars = 0;
for (p = format; *p; ++p)
if (*p == '*') ++num_stars;
va_start(vargs, format);
fprintf(stderr, "%s\tprintf = ", format);
switch (num_stars) {
case 0:
n = fprintf(stderr, format, va_arg(vargs, Double));
break;
case 1:
i1 = va_arg(vargs, int);
n = fprintf(stderr, format, i1, va_arg(vargs, Double));
break;
case 2:
i1 = va_arg(vargs, int);
i2 = va_arg(vargs, int);
n = fprintf(stderr, format, i1, i2, va_arg(vargs, Double));
break;
}
fprintf(stderr, "\twrote %3d chars\n", n);
va_end(vargs);
buf.n = 0;
buf.buf[0] = 0;
fprintf(stderr, "%s\tdebuglog = ", format);
va_start(vargs, format);
n = VG_(debugLog_vprintf)(add_to_buf, &buf, format, vargs);
va_end(vargs);
emit(buf.buf, strlen(buf.buf));
fprintf(stderr, "\twrote %3d chars\n", n);
}
int main(int argc, char *argv[])
{
double value;
fprintf(stderr, "...testing value 0\n");
value = 0.0;
run("|%f|", value);
run("|%2f|", value);
run("|%9f|", value);
run("|%8.0f|", value);
run("|%8.1f|", value);
run("|%8.2f|", value);
fprintf(stderr, "\n");
fprintf(stderr, "...testing value 3.7 (with rounding)\n");
value = 3.7;
run("|%f|", value);
run("|%4f|", value);
run("|%9f|", value);
run("|%4.0f|", value);
run("|%4.1f|", value);
run("|%4.2f|", value);
fprintf(stderr, "\n");
fprintf(stderr, "...testing value 123.01\n");
value = 123.01;
run("|%f|", value);
run("|%4f|", value);
run("|%9f|", value);
run("|%8.0f|", value);
run("|%8.1f|", value);
run("|%8.2f|", value);
run("|%8.3f|", value);
fprintf(stderr, "\n");
fprintf(stderr, "...testing value 3.0019 (with rounding)\n");
value = 3.0019;
run("|%f|", value);
run("|%10f|", value);
run("|%10.0f|", value);
run("|%10.3f|", value);
run("|%10.4f|", value);
run("|%.4f|", value);
run("|%.9f|", value);
fprintf(stderr, "\n");
fprintf(stderr, "...testing value -123.456 (with rounding)\n");
value = -123.456;
run("|%f|", value);
run("|%10f|", value);
run("|%10.0f|", value);
run("|%10.1f|", value);
run("|%10.2f|", value);
run("|%10.3f|", value);
run("|%10.4f|", value);
run("|%10.5f|", value);
run("|%.4f|", value);
fprintf(stderr, "\n");
fprintf(stderr, "...testing value = -123.456 width = '*'\n");
value = -123.456;
run("|%*f|", 10, value);
run("|%*f|", 2, value);
run("|%*f.1|", 10, value);
fprintf(stderr, "\n");
fprintf(stderr, "...testing precision = '*'\n");
value = -123.456;
run("|%.*f|", 10, value);
run("|%.*f|", 2, value);
run("|%10.*f|", 2, value);
fprintf(stderr, "\n");
fprintf(stderr, "...testing width/precision = '*'\n");
value = -123.456;
run("|%*.*f|", 20, 5, value);
run("|%*.*f|", 1, 4, value);
fprintf(stderr, "\n");
fprintf(stderr, "...testing left justification\n");
value = 3.1415;
run("|%10f|", value);
run("|%-10f|", value);
return 0;
}