1/* Test %f format specifier */
2#include <assert.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include "pub_core_basics.h"
8#include "pub_core_libcbase.h"
9#include "pub_core_libcassert.h"
10#include "pub_core_libcprint.h"
11
12#undef vg_assert
13#define vg_assert(e)                   assert(e)
14#undef vg_assert2
15#define vg_assert2(e, fmt, args...)    assert(e)
16
17#include "coregrind/m_debuglog.c"
18
19void run(const char *format, ...)
20{
21  int n, num_stars;
22  const char *p;
23  printf_buf buf;
24  va_list vargs;
25
26  // Count number of '*' in format
27  num_stars = 0;
28  for (p = format; *p; ++p)
29    if (*p == '*') ++num_stars;
30
31  va_start(vargs, format);
32  fprintf(stderr, "%s\tprintf =   ", format);
33  n = vfprintf(stderr, format, vargs);
34  fprintf(stderr, "\twrote %3d chars\n", n);
35  va_end(vargs);
36
37  buf.n = 0;
38  buf.buf[0] = 0;
39
40  fprintf(stderr, "%s\tdebuglog = ", format);
41  va_start(vargs, format);
42  n = VG_(debugLog_vprintf)(add_to_buf, &buf, format, vargs);
43  va_end(vargs);
44
45  emit(buf.buf, strlen(buf.buf));
46  fprintf(stderr, "\twrote %3d chars\n", n);
47}
48
49int main(int argc, char *argv[])
50{
51  double value;
52
53  fprintf(stderr, "...testing value 0\n");
54  value = 0.0;
55  run("|%f|", value);
56  run("|%2f|", value);
57  run("|%9f|", value);
58  run("|%8.0f|", value);
59  run("|%8.1f|", value);
60  run("|%8.2f|", value);
61
62  fprintf(stderr, "\n");
63  fprintf(stderr, "...testing value 3.7  (with rounding)\n");
64  value = 3.7;
65  run("|%f|", value);
66  run("|%4f|", value);
67  run("|%9f|", value);
68  run("|%4.0f|", value);
69  run("|%4.1f|", value);
70  run("|%4.2f|", value);
71
72  fprintf(stderr, "\n");
73  fprintf(stderr, "...testing value 123.01\n");
74  value = 123.01;
75  run("|%f|", value);
76  run("|%4f|", value);
77  run("|%9f|", value);
78  run("|%8.0f|", value);
79  run("|%8.1f|", value);
80  run("|%8.2f|", value);
81  run("|%8.3f|", value);
82
83  fprintf(stderr, "\n");
84  fprintf(stderr, "...testing value 3.0019  (with rounding)\n");
85  value = 3.0019;
86  run("|%f|", value);
87  run("|%10f|", value);
88  run("|%10.0f|", value);
89  run("|%10.3f|", value);
90  run("|%10.4f|", value);
91  run("|%.4f|", value);
92  run("|%.9f|", value);
93
94  fprintf(stderr, "\n");
95  fprintf(stderr, "...testing value -123.456 (with rounding)\n");
96  value = -123.456;
97  run("|%f|", value);
98  run("|%10f|", value);
99  run("|%10.0f|", value);
100  run("|%10.1f|", value);
101  run("|%10.2f|", value);
102  run("|%10.3f|", value);
103  run("|%10.4f|", value);
104  run("|%10.5f|", value);
105  run("|%.4f|", value);
106
107  fprintf(stderr, "\n");
108  fprintf(stderr, "...testing value = -123.456 width = '*'\n");
109  value = -123.456;
110  run("|%*f|", 10, value);
111  run("|%*f|", 2, value);
112  run("|%*f.1|", 10, value);
113
114  fprintf(stderr, "\n");
115  fprintf(stderr, "...testing precision = '*'\n");
116  value = -123.456;
117  run("|%.*f|", 10, value);
118  run("|%.*f|", 2, value);
119  run("|%10.*f|", 2, value);
120
121  fprintf(stderr, "\n");
122  fprintf(stderr, "...testing width/precision = '*'\n");
123  value = -123.456;
124  run("|%*.*f|", 20, 5, value);
125  run("|%*.*f|", 1, 4, value);
126
127  fprintf(stderr, "\n");
128  fprintf(stderr, "...testing left justification\n");
129  value = 3.1415;
130  run("|%10f|", value);
131  run("|%-10f|", value);
132
133  fprintf(stderr, "\n");
134  fprintf(stderr, "...testing strings\n");
135  const char *str = "abcd";
136  run("|%s|", str);
137  run("|%9s|", str);
138  run("|%-9s|", str);
139  run("|%*s|", 6, str);
140
141  fprintf(stderr, "\n");
142  fprintf(stderr, "...testing integers\n");
143  long long ival = -1004005;
144  run("|%lld|", ival);
145  //  runint("|%'lld|", ival);     // locale specific (LC_NUMERIC)
146  run("|%15lld|", ival);
147  run("|%-15lld|", ival);
148  //  runint("|%'-15lld|", ival);  // locale specific (LC_NUMERIC)
149  run("|%100lld|", ival);
150  run("|%*lld|", 13, ival);
151
152  value = 0.99685224;
153  run("|%3.0f|", value);
154  run("|%3.1f|", value);
155  run("|%3.2f|", value);
156  run("|%3.3f|", value);
157  run("|%3.4f|", value);
158  run("|%3.5f|", value);
159
160  return 0;
161}
162