summaryrefslogtreecommitdiff
path: root/test/printf-tests.c
blob: 666c20c3538481e0e46088c4d35bcd461671d6f7 (plain)
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* Copyright © 2013 Bart Massey */
/* This program is licensed under the GPL version 2 or later.
   Please see the file COPYING.GPL2 in this distribution for
   license terms. */

#define _GNU_SOURCE
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

#ifndef TINY_STDIO
#define printf_float(x) x
#ifdef _NANO_FORMATTED_IO
#ifndef NO_FLOATING_POINT
extern int _printf_float();
extern int _scanf_float();

int (*_reference_printf_float)() = _printf_float;
int (*_reference_scanf_float)() = _scanf_float;
#define TEST_ASPRINTF
#endif
#endif
#endif

static char buf[1024];

static void failmsg(int serial, char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    printf("test %d failed: ", serial);
    vprintf(fmt, ap);
    printf("\n");
    va_end(ap);
}

static int test(int serial, char *expect, char *fmt, ...) {
    va_list ap;
    char *abuf = NULL;
    va_start(ap, fmt);
    int n;
#ifdef TEST_ASPRINTF
    int an;
    va_list aap;
    va_copy(aap, ap);
#endif
#ifndef NO_FLOATING_POINT
    double dv;
    char *star;
#endif
    switch (fmt[strlen(fmt)-1]) {
    case 'e':
    case 'E':
    case 'f':
    case 'F':
    case 'g':
    case 'G':
#ifdef NO_FLOATING_POINT
	    return 0;
#else
	    star = strchr(fmt, '*');
	    if (star) {
		    if (strchr(star+1, '*')) {
			    int iv1 = va_arg(ap, int);
			    int iv2 = va_arg(ap, int);
			    dv = va_arg(ap, double);
			    n = snprintf(buf, 1024, fmt, iv1, iv2, printf_float(dv));
#ifdef TEST_ASPRINTF
			    an = asprintf(&abuf, fmt, iv1, iv2, printf_float(dv));
#endif
		    } else  {
			    int iv = va_arg(ap, int);
			    dv = va_arg(ap, double);
			    n = snprintf(buf, 1024, fmt, iv, printf_float(dv));
#ifdef TEST_ASPRINTF
			    an = asprintf(&abuf, fmt, iv, printf_float(dv));
#endif
		    }
	    } else {
		    dv = va_arg(ap, double);
		    n = snprintf(buf, 1024, fmt, printf_float(dv));
#ifdef TEST_ASPRINTF
		    an = asprintf(&abuf, fmt, printf_float(dv));
#endif
	    }
	    break;
#endif
    default:
	    n = vsnprintf(buf, 1024, fmt, ap);
#ifdef TEST_ASPRINTF
	    an = vasprintf(&abuf, fmt, aap);
#endif
	    break;
    }
    va_end(ap);
#ifdef TEST_ASPRINTF
    va_end(aap);
#endif
    if (n >= 1024) {
        failmsg(serial, "buffer overflow");
	free(abuf);
        return 1;
    }
    if (n != strlen(expect)) {
        failmsg(serial, "expected \"%s\" (%d), got \"%s\" (%d)",
		expect, strlen(expect), buf, n);
	free(abuf);
        return 1;
    }
    if (strcmp(buf, expect)) {
        failmsg(serial, "expected \"%s\", got \"%s\"", expect, buf);
	free(abuf);
        return 1;
    }
#ifdef TEST_ASPRINTF
    if (an != n) {
	failmsg(serial, "asprintf return %d sprintf return %d\n", an, n);
	free(abuf);
	return 1;
    }
    if (strcmp(abuf, buf)) {
	failmsg(serial, "sprintf return %s asprintf return %s\n", buf, abuf);
	free(abuf);
	return 1;
    }
    free(abuf);
#endif
    return 0;
}

int main() {
    int result = 0;
#include "testcases.c"
    return result;
}