1 /*
2 *
3 * Copyright (C) 2005-2007 Peter Johnson
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "libyasm/intnum.c"
31
32 typedef struct Test_Entry {
33 /* signedness (0=unsigned, 1=signed) */
34 int sign;
35
36 /* whether input value should be negated */
37 int negate;
38
39 /* input value (as hex string) */
40 const char *input;
41
42 /* correct size returned from both size_leb128 and get_leb128 */
43 unsigned long outsize;
44
45 /* correct return data from get_leb128 */
46 const unsigned char *result;
47 } Test_Entry;
48
49 static Test_Entry tests[] = {
50 /* Unsigned values */
51 {0, 0, "0", 1, (const unsigned char *)"\x00"},
52 {0, 0, "2", 1, (const unsigned char *)"\x02"},
53 {0, 0, "7F", 1, (const unsigned char *)"\x7F"},
54 {0, 0, "80", 2, (const unsigned char *)"\x80\x01"},
55 {0, 0, "81", 2, (const unsigned char *)"\x81\x01"},
56 {0, 0, "82", 2, (const unsigned char *)"\x82\x01"},
57 {0, 0, "3239", 2, (const unsigned char *)"\xB9\x64"},
58 /* Signed zero value */
59 {1, 0, "0", 1, (const unsigned char *)"\x00"},
60 /* Signed positive values */
61 {1, 0, "2", 1, (const unsigned char *)"\x02"},
62 {1, 0, "7F", 2, (const unsigned char *)"\xFF\x00"},
63 {1, 0, "80", 2, (const unsigned char *)"\x80\x01"},
64 {1, 0, "81", 2, (const unsigned char *)"\x81\x01"},
65 /* Signed negative values */
66 {1, 1, "2", 1, (const unsigned char *)"\x7E"},
67 {1, 1, "7F", 2, (const unsigned char *)"\x81\x7F"},
68 {1, 1, "80", 2, (const unsigned char *)"\x80\x7F"},
69 {1, 1, "81", 2, (const unsigned char *)"\xFF\x7E"},
70 };
71
72 static char failed[1000];
73 static char failmsg[100];
74
75 static int
run_output_test(Test_Entry * test)76 run_output_test(Test_Entry *test)
77 {
78 char *valstr = yasm__xstrdup(test->input);
79 yasm_intnum *intn = yasm_intnum_create_hex(valstr);
80 unsigned long size, i;
81 unsigned char out[100];
82 int bad;
83
84 yasm_xfree(valstr);
85
86 if (test->negate)
87 yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
88
89 size = yasm_intnum_size_leb128(intn, test->sign);
90 if (size != test->outsize) {
91 yasm_intnum_destroy(intn);
92 sprintf(failmsg, "%ssigned %s%s size() bad size: expected %lu, got %lu!",
93 test->sign?"":"un", test->negate?"-":"", test->input,
94 test->outsize, size);
95 return 1;
96 }
97
98 for (i=0; i<sizeof(out); i++)
99 out[i] = 0xFF;
100 size = yasm_intnum_get_leb128(intn, out, test->sign);
101 if (size != test->outsize) {
102 yasm_intnum_destroy(intn);
103 sprintf(failmsg, "%ssigned %s%s get() bad size: expected %lu, got %lu!",
104 test->sign?"":"un", test->negate?"-":"", test->input,
105 test->outsize, size);
106 return 1;
107 }
108
109 bad = 0;
110 for (i=0; i<test->outsize && !bad; i++) {
111 if (out[i] != test->result[i])
112 bad = 1;
113 }
114 if (bad) {
115 yasm_intnum_destroy(intn);
116 sprintf(failmsg, "%ssigned %s%s get() bad output!",
117 test->sign?"":"un", test->negate?"-":"", test->input);
118 return 1;
119 }
120
121 yasm_intnum_destroy(intn);
122 return 0;
123 }
124
125 static int
run_input_test(Test_Entry * test)126 run_input_test(Test_Entry *test)
127 {
128 char *valstr = yasm__xstrdup(test->input);
129 yasm_intnum *intn = yasm_intnum_create_hex(valstr);
130 yasm_intnum *testn;
131 unsigned long size;
132
133 yasm_xfree(valstr);
134
135 if (test->negate)
136 yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
137
138 testn = yasm_intnum_create_leb128(test->result, test->sign, &size);
139 if (size != test->outsize) {
140 yasm_intnum_destroy(testn);
141 yasm_intnum_destroy(intn);
142 sprintf(failmsg, "%ssigned %s%s create() bad size: expected %lu, got %lu!",
143 test->sign?"":"un", test->negate?"-":"", test->input,
144 test->outsize, size);
145 return 1;
146 }
147
148 yasm_intnum_calc(intn, YASM_EXPR_EQ, testn);
149 if (!yasm_intnum_is_pos1(intn)) {
150 yasm_intnum_destroy(testn);
151 yasm_intnum_destroy(intn);
152 sprintf(failmsg, "%ssigned %s%s create() bad output!",
153 test->sign?"":"un", test->negate?"-":"", test->input);
154 return 1;
155 }
156
157 yasm_intnum_destroy(testn);
158 yasm_intnum_destroy(intn);
159 return 0;
160 }
161
162 int
main(void)163 main(void)
164 {
165 int nf = 0;
166 int numtests = sizeof(tests)/sizeof(Test_Entry);
167 int i;
168
169 if (BitVector_Boot() != ErrCode_Ok)
170 return EXIT_FAILURE;
171 yasm_intnum_initialize();
172
173 failed[0] = '\0';
174 printf("Test leb128_test: ");
175 for (i=0; i<numtests; i++) {
176 int fail;
177
178 fail = run_output_test(&tests[i]);
179 printf("%c", fail>0 ? 'F':'.');
180 fflush(stdout);
181 if (fail)
182 sprintf(failed, "%s ** F: %s\n", failed, failmsg);
183 nf += fail;
184
185 fail = run_input_test(&tests[i]);
186 printf("%c", fail>0 ? 'F':'.');
187 fflush(stdout);
188 if (fail)
189 sprintf(failed, "%s ** F: %s\n", failed, failmsg);
190 nf += fail;
191 }
192
193 yasm_intnum_cleanup();
194
195 printf(" +%d-%d/%d %d%%\n%s",
196 numtests*2-nf, nf, numtests*2, 100*(numtests*2-nf)/(numtests*2),
197 failed);
198 return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
199 }
200