1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#include <stdio.h>
#include <stdarg.h>
void vary(const char *s, ...) {
va_list v;
va_start(v, s);
char d[20];
vsnprintf(d, 20, s, v);
puts(d);
// Try it with copying
va_list tempva;
va_copy(tempva, v);
vsnprintf(d, 20, s, tempva);
puts(d);
va_end(v);
}
void vary2(char color, const char *s, ...) {
va_list v;
va_start(v, s);
char d[21];
d[0] = color;
vsnprintf(d + 1, 20, s, v);
puts(d);
va_end(v);
}
void varargs_listoffsets_list_evaluate(int count, va_list ap, int vaIteration) {
while (count > 0) {
const char *string = va_arg(ap, const char *);
printf("%s", string);
count--;
}
printf("\n");
}
void varags_listoffsets_list_copy(int count, va_list ap, int iteration) {
va_list ap_copy;
va_copy(ap_copy, ap);
varargs_listoffsets_list_evaluate(count, ap_copy, iteration);
va_end(ap_copy);
}
void varargs_listoffsets_args(int type, int count, ...) {
va_list ap;
va_start(ap, count);
// evaluate a copied list
varags_listoffsets_list_copy(count, ap, 1);
varags_listoffsets_list_copy(count, ap, 2);
varags_listoffsets_list_copy(count, ap, 3);
varags_listoffsets_list_copy(count, ap, 4);
varargs_listoffsets_list_evaluate(count, ap, 1);
// NOTE: we expect this test to fail, so we will check the stdout for
// <BAD+0><BAD+1>.....
varargs_listoffsets_list_evaluate(count, ap, 2);
// NOTE: this test has to work again, as we restart the list
va_end(ap);
va_start(ap, count);
varargs_listoffsets_list_evaluate(count, ap, 3);
va_end(ap);
}
void varargs_listoffsets_main() {
varargs_listoffsets_args(0, 5, "abc", "def", "ghi", "jkl", "mno", "<BAD+0>",
"<BAD+1>", "<BAD+2>", "<BAD+3>", "<BAD+4>",
"<BAD+5>", "<BAD+6>", "<BAD+7>", "<BAD+8>",
"<BAD+9>", "<BAD+10>", "<BAD+11>", "<BAD+12>",
"<BAD+13>", "<BAD+14>", "<BAD+15>", "<BAD+16>");
}
#define GETMAX(pref, type) \
type getMax##pref(int num, ...) { \
va_list vv; \
va_start(vv, num); \
type maxx = va_arg(vv, type); \
for (int i = 1; i < num; i++) { \
type curr = va_arg(vv, type); \
maxx = curr > maxx ? curr : maxx; \
} \
va_end(vv); \
return maxx; \
}
GETMAX(i, int);
GETMAX(D, double);
int main(int argc, char **argv) {
vary("*cheez: %d+%d*", 0,
24); // Also tests that '0' is not special as an array ender
vary("*albeit*"); // Should not fail with no var args in vararg function
vary2('Q', "%d*", 85);
int maxxi = getMaxi(6, 2, 5, 21, 4, -10, 19);
printf("maxxi:%d*\n", maxxi);
double maxxD = getMaxD(6, (double)2.1, (double)5.1, (double)22.1, (double)4.1,
(double)-10.1, (double)19.1, (double)2);
printf("maxxD:%.2f*\n", (float)maxxD);
// And, as a function pointer
void (*vfp)(const char * s, ...) = argc == 1211 ? NULL : vary;
vfp("*vfp:%d,%d*", 22, 199);
// ensure lists work properly when copied, reinited etc.
varargs_listoffsets_main();
return 0;
}
|