[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / polly / lib / External / isl / imath / imdrover.c
blob40860d6346f133de3e267bbabd2c2e222f98edf4
1 /*
2 Name: imdrover.c
3 Purpose: Keeper of the hordes of testing code.
4 Author: M. J. Fromberger
6 Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 SOFTWARE.
27 #include <assert.h>
28 #include <limits.h>
29 #include <stdlib.h>
30 #include <string.h>
32 #include "imath.h"
33 #include "imdrover.h"
34 #include "imrat.h"
35 #include "iprime.h"
37 /* Globals visible from outside this file */
38 mp_result imath_errno;
39 char* imath_errmsg;
41 /* Set imath_errno and return failure from a test. */
42 #define FAIL(E) return (imath_errno = (E), false)
44 /* Check that an expression X yields the expected mp_result value V. */
45 #define VCHECK(X, V) \
46 do { \
47 mp_result res_; \
48 if ((res_ = (X)) != (V)) { \
49 FAIL(res_); \
50 } \
51 } while (0)
52 #define CHECK(X) VCHECK(X, MP_OK)
53 #define ECHECK(X) VCHECK(X, expect)
54 #define ACHECK(X) \
55 do { \
56 if (!(X)) { \
57 FAIL(MP_BADARG); \
58 } \
59 } while (0)
61 #define OUTPUT_LIMIT 2048
62 #define NUM_REGS 16
63 #define OTHER_ERROR -1024
65 static char g_output[OUTPUT_LIMIT];
66 static mpz_t g_zreg[NUM_REGS];
67 static mpq_t g_qreg[NUM_REGS];
68 static unsigned char g_bin1[OUTPUT_LIMIT];
69 static unsigned char g_bin2[OUTPUT_LIMIT];
71 extern void trim_line(char* line); /* borrowed from imtest.c */
73 /* Read in a string with radix tags */
74 static mp_result read_int_value(mp_int z, char* str);
75 static mp_result read_rat_value(mp_rat q, char* str);
77 /* Read in a string with radix tags, as a long (not an mp_int) */
78 static bool read_long(long* z, char* str);
80 /* Parse the input and output values and fill in pointers to the
81 registers containing them. Returns true if all is well, false
82 in case of error. Caller allocates in/out to correct sizes. */
83 static bool parse_int_values(testspec_t* t, mp_int* in, mp_int* out,
84 mp_result* rval);
85 static bool parse_rat_values(testspec_t* t, mp_rat* in, mp_rat* out,
86 mp_result* rval);
88 /* Parse a result code name and return the corresponding result code */
89 static bool parse_result_code(char* str, mp_result* code);
91 /* Read in a dot-delimited binary sequence to the given buffer, and return the
92 number of bytes read. Returns < 0 in case of a syntax error. Records no
93 more than limit bytes. */
94 static int parse_binary(char* str, unsigned char* buf, int limit);
96 /* Clean up registers (called from atexit()) */
97 static void done_testing(void);
100 * Utility subroutines for writing tests (explained above)
103 static mp_result read_int_value(mp_int z, char* str) {
104 int radix = 10;
106 if (*str == '#') {
107 ++str;
108 switch (*str) {
109 case 'x':
110 case 'X':
111 radix = 16;
112 break;
113 case 'd':
114 case 'D':
115 radix = 10;
116 break;
117 case 'o':
118 case 'O':
119 radix = 8;
120 break;
121 case 'b':
122 case 'B':
123 radix = 2;
124 break;
125 default:
126 return MP_RANGE;
128 ++str;
131 return mp_int_read_string(z, radix, str);
134 static mp_result read_rat_value(mp_rat q, char* str) {
135 int radix = 10;
137 if (*str == '#') {
138 ++str;
139 switch (*str) {
140 case 'x':
141 case 'X':
142 radix = 16;
143 break;
144 case 'd':
145 case 'D':
146 radix = 10;
147 break;
148 case 'o':
149 case 'O':
150 radix = 8;
151 break;
152 case 'b':
153 case 'B':
154 radix = 2;
155 break;
156 default:
157 return MP_RANGE;
159 ++str;
162 if (*str == '@')
163 return mp_rat_read_decimal(q, radix, str + 1);
164 else
165 return mp_rat_read_string(q, radix, str);
168 static bool read_long(long* z, char* str) {
169 char* end;
170 int radix = 10;
172 if (*str == '#') {
173 ++str;
174 switch (*str) {
175 case 'x':
176 case 'X':
177 radix = 16;
178 break;
179 case 'd':
180 case 'D':
181 radix = 10;
182 break;
183 case 'o':
184 case 'O':
185 radix = 8;
186 break;
187 case 'b':
188 case 'B':
189 radix = 2;
190 break;
191 default:
192 return false;
194 ++str;
197 *z = strtol(str, &end, radix);
198 return (end != str && *end == '\0');
201 static bool parse_int_values(testspec_t* t, mp_int* in, mp_int* out,
202 mp_result* rval) {
203 int pos = 0;
204 char* str;
206 if (rval != NULL) *rval = MP_OK; /* default */
208 if (in != NULL) {
209 for (int i = 0; i < t->num_inputs; ++i) {
210 str = t->input[i];
212 trim_line(str);
214 if (*str == '=') {
215 int k = abs(atoi(str + 1)) - 1;
217 if (k < 0 || k >= i) {
218 fprintf(stderr, "Line %d: Invalid input back-reference [%s]\n",
219 t->line, str);
220 return false;
223 in[i] = in[k];
224 } else {
225 mp_int reg = g_zreg + pos++; /* grab next free register */
227 if (read_int_value(reg, str) != MP_OK) {
228 fprintf(stderr, "Line %d: Invalid input value [%s]\n", t->line, str);
229 return false;
232 in[i] = reg;
237 for (int i = 0; i < t->num_outputs; ++i) {
238 mp_int reg = g_zreg + pos++;
240 str = t->output[i];
242 trim_line(str);
244 if (strcmp(str, "?") == 0)
245 mp_int_zero(reg);
246 else if (*str == '$') {
247 mp_result code;
249 if (!parse_result_code(str, &code)) {
250 fprintf(stderr, "Line %d: Invalid result code [%s]\n", t->line, str);
251 return false;
252 } else if (rval == NULL) {
253 fprintf(stderr, "Line %d: Result code not permitted here [%s]\n",
254 t->line, str);
255 return false;
256 } else
257 *rval = code;
259 /* Provide a dummy value for the corresponding output */
260 mp_int_zero(reg);
261 } else if (out != NULL && read_int_value(reg, str) != MP_OK) {
262 fprintf(stderr, "Line %d: Invalid output value [%s]\n", t->line, str);
263 return false;
266 if (out != NULL) out[i] = reg;
269 return true;
272 static bool parse_rat_values(testspec_t* t, mp_rat* in, mp_rat* out,
273 mp_result* rval) {
274 int pos = 0;
275 char* str;
277 if (rval != NULL) *rval = MP_OK; /* default */
279 if (in != NULL) {
280 for (int i = 0; i < t->num_inputs; ++i) {
281 str = t->input[i];
283 trim_line(str);
285 if (*str == '=') {
286 int k = abs(atoi(str + 1)) - 1;
288 if (k < 0 || k >= i) {
289 fprintf(stderr, "Line %d: Invalid input back-reference [%s]\n",
290 t->line, str);
291 return false;
294 in[i] = in[k];
295 } else {
296 mp_rat reg = g_qreg + pos++; /* grab next free register */
298 if (read_rat_value(reg, str) != MP_OK) {
299 fprintf(stderr, "Line %d: Invalid input value [%s]\n", t->line, str);
300 return false;
303 in[i] = reg;
308 for (int i = 0; i < t->num_outputs; ++i) {
309 mp_rat reg = g_qreg + pos++;
311 str = t->output[i];
313 trim_line(str);
315 if (strcmp(str, "?") == 0)
316 mp_rat_zero(reg);
317 else if (*str == '$') {
318 mp_result code;
320 if (!parse_result_code(str, &code)) {
321 fprintf(stderr, "Line %d: Invalid result code [%s]\n", t->line, str);
322 return false;
323 } else if (rval == NULL) {
324 fprintf(stderr, "Line %d: Result code not permitted here [%s]\n",
325 t->line, str);
326 return false;
327 } else
328 *rval = code;
330 /* Provide a dummy value for the corresponding output */
331 mp_rat_zero(reg);
332 } else if (out != NULL && read_rat_value(reg, str) != MP_OK) {
333 fprintf(stderr, "Line %d: Invalid output value [%s]\n", t->line, str);
334 return false;
337 if (out != NULL) out[i] = reg;
340 return true;
343 static bool parse_result_code(char* str, mp_result* code) {
344 if (str[0] == '$') {
345 if (str[1] == '#') {
346 long v;
348 if (!read_long(&v, str + 2)) return false;
350 *code = (mp_result)v;
351 } else if (strcmp(str + 1, "MP_OK") == 0 ||
352 strcmp(str + 1, "MP_FALSE") == 0) {
353 *code = MP_OK;
354 } else if (strcmp(str + 1, "MP_TRUE") == 0) {
355 *code = MP_TRUE;
356 } else if (strcmp(str + 1, "MP_MEMORY") == 0) {
357 *code = MP_MEMORY;
358 } else if (strcmp(str + 1, "MP_RANGE") == 0) {
359 *code = MP_RANGE;
360 } else if (strcmp(str + 1, "MP_UNDEF") == 0) {
361 *code = MP_UNDEF;
362 } else if (strcmp(str + 1, "MP_TRUNC") == 0) {
363 *code = MP_TRUNC;
364 } else if (strcmp(str + 1, "MP_ROUND_UP") == 0) {
365 *code = MP_ROUND_UP;
366 } else if (strcmp(str + 1, "MP_ROUND_DOWN") == 0) {
367 *code = MP_ROUND_DOWN;
368 } else if (strcmp(str + 1, "MP_ROUND_HALF_UP") == 0) {
369 *code = MP_ROUND_HALF_UP;
370 } else if (strcmp(str + 1, "MP_ROUND_HALF_DOWN") == 0) {
371 *code = MP_ROUND_HALF_DOWN;
372 } else {
373 return false;
377 return true;
380 static int parse_binary(char* str, unsigned char* buf, int limit) {
381 int pos = 0;
382 char* tok;
384 trim_line(str);
386 for (tok = strtok(str, "."); tok != NULL && pos < limit;
387 tok = strtok(NULL, ".")) {
388 long v;
390 if (!read_long(&v, tok) || v > UCHAR_MAX || v < 0) return -1;
392 buf[pos++] = (unsigned char)v;
395 return pos;
398 static void done_testing(void) {
399 int i;
401 for (i = 0; i < NUM_REGS; ++i) {
402 mp_int_clear(g_zreg + i);
403 mp_rat_clear(g_qreg + i);
408 * Global functions visible to callers outside this file.
411 void init_testing(void) {
412 static int is_done = 0;
414 if (is_done) return;
416 for (int i = 0; i < NUM_REGS; ++i) {
417 assert(mp_int_init(g_zreg + i) == MP_OK);
418 assert(mp_rat_init(g_qreg + i) == MP_OK);
421 imath_errmsg = g_output;
423 assert(atexit(done_testing) == 0);
424 is_done = 1;
427 void reset_registers(void) {
428 for (int i = 0; i < NUM_REGS; ++i) {
429 mp_int_zero(g_zreg + i);
430 mp_rat_zero(g_qreg + i);
434 bool test_init(testspec_t* t, FILE* ofp) {
435 mp_int in[2], out[1];
436 mp_small v;
437 mp_usmall uv;
438 mp_result expect;
440 ACHECK(parse_int_values(t, in, out, &expect));
442 if (strcmp(t->code, "initu") == 0) {
443 CHECK(mp_int_to_uint(in[1], &uv));
444 ECHECK(mp_int_init_uvalue(in[0], uv));
445 } else { /* initv */
446 CHECK(mp_int_to_int(in[1], &v));
447 ECHECK(mp_int_init_value(in[0], v));
450 if (expect == MP_OK && mp_int_compare(in[0], out[0]) != 0) {
451 mp_int_to_string(in[0], 10, g_output, OUTPUT_LIMIT);
452 FAIL(OTHER_ERROR);
455 return true;
458 bool test_set(testspec_t* t, FILE* ofp) {
459 mp_int in[2], out[1];
460 mp_small v;
461 mp_usmall uv;
462 mp_result expect;
464 ACHECK(parse_int_values(t, in, out, &expect));
466 if (strcmp(t->code, "setu") == 0) {
467 CHECK(mp_int_to_uint(in[1], &uv));
468 ECHECK(mp_int_set_uvalue(in[0], uv));
469 } else { /* setv */
470 CHECK(mp_int_to_int(in[1], &v));
471 ECHECK(mp_int_set_value(in[0], v));
474 if (expect == MP_OK && mp_int_compare(in[0], out[0]) != 0) {
475 mp_int_to_string(in[0], 10, g_output, OUTPUT_LIMIT);
476 FAIL(OTHER_ERROR);
479 return true;
482 bool test_neg(testspec_t* t, FILE* ofp) {
483 mp_int in[2], out[1];
484 mp_result expect;
486 ACHECK(parse_int_values(t, in, out, &expect));
487 ECHECK(mp_int_neg(in[0], in[1]));
489 if (expect == MP_OK && mp_int_compare(in[1], out[0]) != 0) {
490 mp_int_to_string(in[1], 10, g_output, OUTPUT_LIMIT);
491 FAIL(OTHER_ERROR);
494 return true;
497 bool test_abs(testspec_t* t, FILE* ofp) {
498 mp_int in[2], out[1];
499 mp_result expect;
501 ACHECK(parse_int_values(t, in, out, &expect));
502 ECHECK(mp_int_abs(in[0], in[1]));
504 if (expect == MP_OK && mp_int_compare(in[1], out[0]) != 0) {
505 mp_int_to_string(in[1], 10, g_output, OUTPUT_LIMIT);
506 FAIL(OTHER_ERROR);
509 return true;
512 bool test_add(testspec_t* t, FILE* ofp) {
513 mp_int in[3], out[1];
514 mp_small v;
515 mp_result expect;
517 ACHECK(parse_int_values(t, in, out, &expect));
519 if (strcmp(t->code, "addv") == 0) {
520 CHECK(mp_int_to_int(in[1], &v));
521 ECHECK(mp_int_add_value(in[0], v, in[2]));
522 } else {
523 ECHECK(mp_int_add(in[0], in[1], in[2]));
526 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
527 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
528 FAIL(OTHER_ERROR);
531 return true;
534 bool test_sub(testspec_t* t, FILE* ofp) {
535 mp_int in[3], out[1];
536 mp_small v;
537 mp_result expect;
539 ACHECK(parse_int_values(t, in, out, &expect));
541 if (strcmp(t->code, "subv") == 0) {
542 CHECK(mp_int_to_int(in[1], &v));
543 ECHECK(mp_int_sub_value(in[0], v, in[2]));
544 } else {
545 ECHECK(mp_int_sub(in[0], in[1], in[2]));
548 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
549 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
550 FAIL(OTHER_ERROR);
552 return true;
555 bool test_mul(testspec_t* t, FILE* ofp) {
556 mp_int in[3], out[1];
557 mp_result expect;
559 ACHECK(parse_int_values(t, in, out, &expect));
560 ECHECK(mp_int_mul(in[0], in[1], in[2]));
562 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
563 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
564 FAIL(OTHER_ERROR);
566 return true;
569 bool test_mulp2(testspec_t* t, FILE* ofp) {
570 mp_int in[3], out[1];
571 mp_result expect;
572 mp_small p2;
574 ACHECK(parse_int_values(t, in, out, &expect));
575 CHECK(mp_int_to_int(in[1], &p2));
576 ECHECK(mp_int_mul_pow2(in[0], p2, in[2]));
578 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
579 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
580 FAIL(OTHER_ERROR);
582 return true;
585 bool test_mulv(testspec_t* t, FILE* ofp) {
586 mp_int in[3], out[1];
587 mp_result expect;
588 mp_small v;
590 ACHECK(parse_int_values(t, in, out, &expect));
591 CHECK(mp_int_to_int(in[1], &v));
592 ECHECK(mp_int_mul_value(in[0], v, in[2]));
594 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
595 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
596 FAIL(OTHER_ERROR);
598 return true;
601 bool test_sqr(testspec_t* t, FILE* ofp) {
602 mp_int in[2], out[1];
603 mp_result expect;
605 ACHECK(parse_int_values(t, in, out, &expect));
606 ECHECK(mp_int_sqr(in[0], in[1]));
608 if (expect == MP_OK && mp_int_compare(in[1], out[0]) != 0) {
609 mp_int_to_string(in[1], 10, g_output, OUTPUT_LIMIT);
610 FAIL(OTHER_ERROR);
612 return true;
615 bool test_div(testspec_t* t, FILE* ofp) {
616 mp_int in[4], out[2];
617 mp_result expect;
619 ACHECK(parse_int_values(t, in, out, &expect));
620 ECHECK(mp_int_div(in[0], in[1], in[2], in[3]));
622 if (expect == MP_OK && ((mp_int_compare(in[2], out[0]) != 0) ||
623 (mp_int_compare(in[3], out[1]) != 0))) {
624 int len;
625 char* str;
627 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
628 str = g_output + (len = strlen(g_output));
629 *str++ = ',';
630 mp_int_to_string(in[3], 10, str, OUTPUT_LIMIT - (len + 1));
631 FAIL(OTHER_ERROR);
633 return true;
636 bool test_divp2(testspec_t* t, FILE* ofp) {
637 mp_int in[4], out[2];
638 mp_result expect;
639 mp_small p2;
641 ACHECK(parse_int_values(t, in, out, &expect));
642 CHECK(mp_int_to_int(in[1], &p2));
643 ECHECK(mp_int_div_pow2(in[0], p2, in[2], in[3]));
645 if (expect == MP_OK && ((mp_int_compare(in[2], out[0]) != 0) ||
646 (mp_int_compare(in[3], out[1]) != 0))) {
647 int len;
648 char* str;
650 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
651 str = g_output + (len = strlen(g_output));
652 *str++ = ',';
653 mp_int_to_string(in[3], 10, str, OUTPUT_LIMIT - (len + 1));
654 FAIL(OTHER_ERROR);
656 return true;
659 bool test_divv(testspec_t* t, FILE* ofp) {
660 mp_int in[3], out[2];
661 mp_result expect;
662 mp_small v, rem, orem;
664 ACHECK(parse_int_values(t, in, out, &expect));
665 CHECK(mp_int_to_int(in[1], &v));
666 CHECK(mp_int_to_int(out[1], &orem));
667 ECHECK(mp_int_div_value(in[0], v, in[2], &rem));
669 if (expect == MP_OK &&
670 ((mp_int_compare(in[2], out[0]) != 0) || (rem != orem))) {
671 char* str;
673 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
674 str = g_output + strlen(g_output);
675 *str++ = ',';
676 sprintf(str, "%ld", rem);
677 FAIL(OTHER_ERROR);
679 return true;
682 bool test_expt(testspec_t* t, FILE* ofp) {
683 mp_int in[3], out[1];
684 mp_result expect;
685 mp_small pow;
687 ACHECK(parse_int_values(t, in, out, &expect));
688 CHECK(mp_int_to_int(in[1], &pow));
689 ECHECK(mp_int_expt(in[0], pow, in[2]));
691 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
692 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
693 FAIL(OTHER_ERROR);
695 return true;
698 bool test_exptv(testspec_t* t, FILE* ofp) {
699 mp_int in[3], out[1];
700 mp_result expect;
701 mp_small a, b;
703 ACHECK(parse_int_values(t, in, out, &expect));
704 CHECK(mp_int_to_int(in[0], &a));
705 CHECK(mp_int_to_int(in[1], &b));
706 ECHECK(mp_int_expt_value(a, b, in[2]));
708 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
709 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
710 FAIL(OTHER_ERROR);
712 return true;
715 bool test_exptf(testspec_t* t, FILE* ofp) {
716 mp_int in[3], out[1];
717 mp_result expect;
719 ACHECK(parse_int_values(t, in, out, &expect));
720 ECHECK(mp_int_expt_full(in[0], in[1], in[2]));
722 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
723 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
724 FAIL(OTHER_ERROR);
726 return true;
729 bool test_mod(testspec_t* t, FILE* ofp) {
730 mp_int in[3], out[1];
731 mp_result expect;
733 ACHECK(parse_int_values(t, in, out, &expect));
734 ECHECK(mp_int_mod(in[0], in[1], in[2]));
736 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
737 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
738 FAIL(OTHER_ERROR);
740 return true;
743 bool test_gcd(testspec_t* t, FILE* ofp) {
744 mp_int in[3], out[1];
745 mp_result expect;
747 ACHECK(parse_int_values(t, in, out, &expect));
748 ECHECK(mp_int_gcd(in[0], in[1], in[2]));
750 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
751 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
752 FAIL(OTHER_ERROR);
754 return true;
757 bool test_egcd(testspec_t* t, FILE* ofp) {
758 mp_int in[5], out[3], t1 = g_zreg + 8, t2 = g_zreg + 9;
759 mp_result expect;
761 ACHECK(parse_int_values(t, in, out, &expect));
762 ECHECK(mp_int_egcd(in[0], in[1], in[2], in[3], in[4]));
764 /* If we got an error we expected, return success immediately */
765 if (expect != MP_OK) return true;
767 if ((mp_int_compare(in[2], out[0]) != 0) ||
768 (mp_int_compare(in[3], out[1]) != 0) ||
769 (mp_int_compare(in[4], out[2]) != 0)) {
770 int len, len2;
771 char* str;
773 /* Failure might occur because the tester computed x and y in a different
774 way than we did. Verify that the results are correct before reporting
775 an error. */
776 mp_int_mul(in[3], in[0], t1);
777 mp_int_mul(in[4], in[1], t2);
778 mp_int_add(t1, t2, t2);
779 if (mp_int_compare(t2, in[2]) == 0) return true;
781 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
782 str = g_output + (len = strlen(g_output));
783 *str++ = ',';
784 mp_int_to_string(in[3], 10, str, OUTPUT_LIMIT - (len + 1));
785 str = str + (len2 = strlen(str));
786 *str++ = ',';
787 mp_int_to_string(in[4], 10, str, OUTPUT_LIMIT - (len + len2 + 2));
788 FAIL(OTHER_ERROR);
790 return true;
793 bool test_lcm(testspec_t* t, FILE* ofp) {
794 mp_int in[3], out[1];
795 mp_result expect;
797 ACHECK(parse_int_values(t, in, out, &expect));
798 ECHECK(mp_int_lcm(in[0], in[1], in[2]));
800 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
801 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
802 FAIL(OTHER_ERROR);
804 return true;
807 bool test_sqrt(testspec_t* t, FILE* ofp) {
808 mp_int in[2], out[1];
809 mp_result expect;
811 ACHECK(parse_int_values(t, in, out, &expect));
812 ECHECK(mp_int_sqrt(in[0], in[1]));
814 if (expect == MP_OK && mp_int_compare(in[1], out[0]) != 0) {
815 mp_int_to_string(in[1], 10, g_output, OUTPUT_LIMIT);
816 FAIL(OTHER_ERROR);
818 return true;
821 bool test_root(testspec_t* t, FILE* ofp) {
822 mp_int in[3], out[1];
823 mp_small v;
824 mp_result expect;
826 ACHECK(parse_int_values(t, in, out, &expect));
827 CHECK(mp_int_to_int(in[1], &v));
828 ECHECK(mp_int_root(in[0], v, in[2]));
830 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
831 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
832 FAIL(OTHER_ERROR);
834 return true;
837 bool test_invmod(testspec_t* t, FILE* ofp) {
838 mp_int in[3], out[1];
839 mp_result expect;
841 ACHECK(parse_int_values(t, in, out, &expect));
842 ECHECK(mp_int_invmod(in[0], in[1], in[2]));
844 if (expect == MP_OK && mp_int_compare(in[2], out[0]) != 0) {
845 mp_int_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
846 FAIL(OTHER_ERROR);
848 return true;
851 bool test_exptmod(testspec_t* t, FILE* ofp) {
852 mp_int in[4], out[1];
853 mp_result expect;
855 ACHECK(parse_int_values(t, in, out, &expect));
856 ECHECK(mp_int_exptmod(in[0], in[1], in[2], in[3]));
858 if (expect == MP_OK && mp_int_compare(in[3], out[0]) != 0) {
859 mp_int_to_string(in[3], 10, g_output, OUTPUT_LIMIT);
860 FAIL(OTHER_ERROR);
862 return true;
865 bool test_exptmod_ev(testspec_t* t, FILE* ofp) {
866 mp_int in[4], out[1];
867 mp_result expect;
868 mp_small v;
870 ACHECK(parse_int_values(t, in, out, &expect));
871 CHECK(mp_int_to_int(in[1], &v));
872 ECHECK(mp_int_exptmod_evalue(in[0], v, in[2], in[3]));
874 if (expect == MP_OK && mp_int_compare(in[3], out[0]) != 0) {
875 mp_int_to_string(in[3], 10, g_output, OUTPUT_LIMIT);
876 FAIL(OTHER_ERROR);
878 return true;
881 bool test_exptmod_bv(testspec_t* t, FILE* ofp) {
882 mp_int in[4], out[1];
883 mp_result expect;
884 mp_small v;
886 ACHECK(parse_int_values(t, in, out, &expect));
887 CHECK(mp_int_to_int(in[0], &v));
888 ECHECK(mp_int_exptmod_bvalue(v, in[1], in[2], in[3]));
890 if (expect == MP_OK && mp_int_compare(in[3], out[0]) != 0) {
891 mp_int_to_string(in[3], 10, g_output, OUTPUT_LIMIT);
892 FAIL(OTHER_ERROR);
894 return true;
897 bool test_comp(testspec_t* t, FILE* ofp) {
898 mp_int in[2];
899 mp_result res, expect;
901 ACHECK(parse_int_values(t, in, NULL, &expect));
903 if ((res = mp_int_compare(in[0], in[1])) != expect) {
904 sprintf(g_output, "Incorrect comparison result (want %d, got %d)", expect,
905 res);
906 FAIL(OTHER_ERROR);
908 return true;
911 bool test_ucomp(testspec_t* t, FILE* ofp) {
912 mp_int in[2];
913 mp_result res, expect;
915 ACHECK(parse_int_values(t, in, NULL, &expect));
917 if ((res = mp_int_compare_unsigned(in[0], in[1])) != expect) {
918 sprintf(g_output, "Incorrect comparison result (want %d, got %d)", expect,
919 res);
920 FAIL(OTHER_ERROR);
922 return true;
925 bool test_zcomp(testspec_t* t, FILE* ofp) {
926 mp_int in[1];
927 mp_result res, expect;
929 ACHECK(parse_int_values(t, in, NULL, &expect));
931 if ((res = mp_int_compare_zero(in[0])) != expect) {
932 sprintf(g_output, "Incorrect comparison result (want %d, got %d)", expect,
933 res);
934 FAIL(OTHER_ERROR);
936 return true;
939 bool test_vcomp(testspec_t* t, FILE* ofp) {
940 mp_int in[2];
941 mp_result res, expect;
942 mp_small v;
944 ACHECK(parse_int_values(t, in, NULL, &expect));
946 v = atoi(t->input[1]);
947 if ((res = mp_int_compare_value(in[0], v)) != expect) {
948 sprintf(g_output, "Incorrect comparison result (want %d, got %d)", expect,
949 res);
950 FAIL(OTHER_ERROR);
952 return true;
955 bool test_uvcomp(testspec_t* t, FILE* ofp) {
956 mp_int in[2];
957 mp_result res, expect;
958 mp_usmall v;
960 ACHECK(parse_int_values(t, in, NULL, &expect));
962 v = strtoul(t->input[1], NULL, 0);
963 if ((res = mp_int_compare_uvalue(in[0], v)) != expect) {
964 sprintf(g_output, "Incorrect comparison result (want %d, got %d)", expect,
965 res);
966 FAIL(OTHER_ERROR);
968 return true;
971 bool test_tostr(testspec_t* t, FILE* ofp) {
972 mp_int in[2];
973 mp_small radix;
974 mp_result len;
976 ACHECK(parse_int_values(t, in, NULL, NULL));
977 ACHECK(mp_int_to_int(in[1], &radix) == MP_OK);
979 if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) FAIL(MP_RANGE);
981 trim_line(t->output[0]);
982 len = mp_int_string_len(in[0], radix);
984 CHECK(mp_int_to_string(in[0], radix, g_output, len));
986 if (strcmp(t->output[0], g_output) != 0) FAIL(OTHER_ERROR);
988 return true;
991 bool test_tobin(testspec_t* t, FILE* ofp) {
992 mp_int in[1];
993 int test_len, out_len;
995 ACHECK(parse_int_values(t, in, NULL, NULL));
997 trim_line(t->output[0]);
998 if ((out_len = parse_binary(t->output[0], g_bin1, sizeof(g_bin1))) < 0)
999 FAIL(MP_BADARG);
1001 if ((test_len = mp_int_binary_len(in[0])) != out_len) {
1002 sprintf(g_output, "Output lengths do not match (want %d, got %d)", test_len,
1003 out_len);
1004 FAIL(OTHER_ERROR);
1007 CHECK(mp_int_to_binary(in[0], g_bin2, sizeof(g_bin2)));
1009 if (memcmp(g_bin1, g_bin2, test_len) != 0) {
1010 int pos = 0, i;
1012 for (i = 0; i < test_len - 1; ++i)
1013 pos += sprintf(g_output + pos, "%d.", g_bin2[i]);
1015 sprintf(g_output + pos, "%d", g_bin2[i]);
1016 FAIL(OTHER_ERROR);
1018 return true;
1021 bool test_to_int(testspec_t* t, FILE* ofp) {
1022 mp_int in[1], out[1];
1023 mp_small v;
1024 mp_result expect;
1026 ACHECK(parse_int_values(t, in, out, &expect));
1027 ECHECK(mp_int_to_int(in[0], &v));
1029 if (expect == MP_OK && mp_int_compare_value(out[0], v) != 0) {
1030 sprintf(g_output, "Incorrect value (got %ld)", v);
1031 FAIL(OTHER_ERROR);
1033 return true;
1036 bool test_to_uint(testspec_t* t, FILE* ofp) {
1037 mp_int in[1], out[1];
1038 mp_usmall v;
1039 mp_result expect;
1041 ACHECK(parse_int_values(t, in, out, &expect));
1042 ECHECK(mp_int_to_uint(in[0], &v));
1044 if (expect == MP_OK && mp_int_compare_uvalue(out[0], v) != 0) {
1045 sprintf(g_output, "Incorrect value (got %lu)", v);
1046 FAIL(OTHER_ERROR);
1048 return true;
1051 bool test_read_binary(testspec_t* t, FILE* ofp) {
1052 mp_int out[1], in = g_zreg + 1;
1053 int in_len;
1054 mp_result expect;
1056 ACHECK(parse_int_values(t, NULL, out, &expect));
1058 trim_line(t->input[0]);
1059 if ((in_len = parse_binary(t->input[0], g_bin1, sizeof(g_bin1))) < 0)
1060 FAIL(MP_BADARG);
1062 ECHECK(mp_int_read_binary(in, g_bin1, in_len));
1064 if (expect == MP_OK && mp_int_compare(in, out[0]) != 0) {
1065 mp_int_to_string(in, 10, g_output, OUTPUT_LIMIT);
1066 FAIL(OTHER_ERROR);
1068 return true;
1071 bool test_to_uns(testspec_t* t, FILE* ofp) {
1072 mp_int in[1];
1073 int test_len, out_len;
1075 ACHECK(parse_int_values(t, in, NULL, NULL));
1077 trim_line(t->output[0]);
1078 if ((out_len = parse_binary(t->output[0], g_bin1, sizeof(g_bin1))) < 0)
1079 FAIL(MP_BADARG);
1081 if ((test_len = mp_int_unsigned_len(in[0])) != out_len) {
1082 sprintf(g_output, "Output lengths do not match (want %d, got %d)", test_len,
1083 out_len);
1084 FAIL(OTHER_ERROR);
1087 CHECK(mp_int_to_unsigned(in[0], g_bin2, sizeof(g_bin2)));
1089 if (memcmp(g_bin1, g_bin2, test_len) != 0) {
1090 int pos = 0, i;
1092 for (i = 0; i < test_len - 1; ++i)
1093 pos += sprintf(g_output + pos, "%d.", g_bin2[i]);
1095 sprintf(g_output + pos, "%d", g_bin2[i]);
1096 FAIL(OTHER_ERROR);
1098 return true;
1101 bool test_read_uns(testspec_t* t, FILE* ofp) {
1102 mp_int out[1], in = g_zreg + 1;
1103 int in_len;
1104 mp_result expect;
1106 ACHECK(parse_int_values(t, NULL, out, &expect));
1108 trim_line(t->input[0]);
1109 if ((in_len = parse_binary(t->input[0], g_bin1, sizeof(g_bin1))) < 0)
1110 FAIL(MP_BADARG);
1112 ECHECK(mp_int_read_unsigned(in, g_bin1, in_len));
1114 if (expect == MP_OK && mp_int_compare(in, out[0]) != 0) {
1115 mp_int_to_string(in, 10, g_output, OUTPUT_LIMIT);
1116 FAIL(OTHER_ERROR);
1118 return true;
1121 bool test_meta(testspec_t* t, FILE* ofp) {
1122 mp_int *in = NULL, *out = NULL;
1123 int i, j;
1124 mp_result expect;
1126 if (t->num_inputs > 0) {
1127 in = calloc(t->num_inputs, sizeof(mp_int));
1129 if (t->num_outputs > 0) {
1130 out = calloc(t->num_outputs, sizeof(mp_int));
1133 if (!parse_int_values(t, in, out, &expect)) {
1134 if (in != NULL) free(in);
1135 if (out != NULL) free(out);
1136 FAIL(MP_BADARG);
1139 fprintf(ofp, "Test '%s' defined at line %d\n", t->code, t->line);
1140 fprintf(ofp, "Expected result: %d\n", expect);
1141 fprintf(ofp, "Input values: %d\n", t->num_inputs);
1142 for (i = 0; i < t->num_inputs; ++i) {
1143 mp_int_to_string(in[i], 10, g_output, OUTPUT_LIMIT);
1145 fprintf(ofp, " %2d.) %s", i + 1, g_output);
1147 for (j = i - 1; j >= 0; --j)
1148 if (in[j] == in[i]) {
1149 fprintf(ofp, " (=> %d)", j + 1);
1150 break;
1153 fputc('\n', ofp);
1155 fprintf(ofp, "Output values: %d\n", t->num_outputs);
1156 for (i = 0; i < t->num_outputs; ++i) {
1157 mp_int_to_string(out[i], 10, g_output, OUTPUT_LIMIT);
1159 fprintf(ofp, " %2d.) %s\n", i + 1, g_output);
1161 if (in != NULL) free(in);
1162 if (out != NULL) free(out);
1163 return true;
1166 bool test_qneg(testspec_t* t, FILE* ofp) {
1167 mp_rat in[2], out[1];
1168 mp_result expect;
1170 ACHECK(parse_rat_values(t, in, out, &expect));
1171 ECHECK(mp_rat_neg(in[0], in[1]));
1173 if (expect == MP_OK && mp_rat_compare(in[1], out[0]) != 0) {
1174 mp_rat_to_string(in[1], 10, g_output, OUTPUT_LIMIT);
1175 FAIL(OTHER_ERROR);
1177 return true;
1180 bool test_qrecip(testspec_t* t, FILE* ofp) {
1181 mp_rat in[2], out[1];
1182 mp_result expect;
1184 ACHECK(parse_rat_values(t, in, out, &expect));
1185 ECHECK(mp_rat_recip(in[0], in[1]));
1187 if (expect == MP_OK && mp_rat_compare(in[1], out[0]) != 0) {
1188 mp_rat_to_string(in[1], 10, g_output, OUTPUT_LIMIT);
1189 FAIL(OTHER_ERROR);
1191 return true;
1194 bool test_qabs(testspec_t* t, FILE* ofp) {
1195 mp_rat in[2], out[1];
1196 mp_result expect;
1198 ACHECK(parse_rat_values(t, in, out, &expect));
1199 ECHECK(mp_rat_abs(in[0], in[1]));
1201 if (expect == MP_OK && mp_rat_compare(in[1], out[0]) != 0) {
1202 mp_rat_to_string(in[1], 10, g_output, OUTPUT_LIMIT);
1203 FAIL(OTHER_ERROR);
1205 return true;
1208 bool test_qadd(testspec_t* t, FILE* ofp) {
1209 mp_rat in[3], out[1];
1210 mp_result expect;
1212 ACHECK(parse_rat_values(t, in, out, &expect));
1213 ECHECK(mp_rat_add(in[0], in[1], in[2]));
1215 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1216 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1217 FAIL(OTHER_ERROR);
1219 return true;
1222 bool test_qsub(testspec_t* t, FILE* ofp) {
1223 mp_rat in[3], out[1];
1224 mp_result expect;
1226 ACHECK(parse_rat_values(t, in, out, &expect));
1227 ECHECK(mp_rat_sub(in[0], in[1], in[2]));
1229 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1230 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1231 FAIL(OTHER_ERROR);
1233 return true;
1236 bool test_qmul(testspec_t* t, FILE* ofp) {
1237 mp_rat in[3], out[1];
1238 mp_result expect;
1240 ACHECK(parse_rat_values(t, in, out, &expect));
1241 ECHECK(mp_rat_mul(in[0], in[1], in[2]));
1243 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1244 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1245 FAIL(OTHER_ERROR);
1247 return true;
1250 bool test_qdiv(testspec_t* t, FILE* ofp) {
1251 mp_rat in[3], out[1];
1252 mp_result expect;
1254 ACHECK(parse_rat_values(t, in, out, &expect));
1255 ECHECK(mp_rat_div(in[0], in[1], in[2]));
1257 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1258 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1259 FAIL(OTHER_ERROR);
1261 return true;
1264 bool test_qaddz(testspec_t* t, FILE* ofp) {
1265 mp_rat in[3], out[1];
1266 mp_result expect;
1268 ACHECK(parse_rat_values(t, in, out, &expect));
1270 if (!mp_rat_is_integer(in[1])) {
1271 fprintf(stderr,
1272 "Line %d: Second argument must be an integer (test_qaddz)\n",
1273 t->line);
1274 FAIL(MP_BADARG);
1277 ECHECK(mp_rat_add_int(in[0], MP_NUMER_P(in[1]), in[2]));
1279 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1280 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1281 FAIL(OTHER_ERROR);
1283 return true;
1286 bool test_qsubz(testspec_t* t, FILE* ofp) {
1287 mp_rat in[3], out[1];
1288 mp_result expect;
1290 ACHECK(parse_rat_values(t, in, out, &expect));
1292 if (!mp_rat_is_integer(in[1])) {
1293 fprintf(stderr,
1294 "Line %d: Second argument must be an integer (test_qsubz)\n",
1295 t->line);
1296 FAIL(MP_BADARG);
1299 ECHECK(mp_rat_sub_int(in[0], MP_NUMER_P(in[1]), in[2]));
1301 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1302 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1303 FAIL(OTHER_ERROR);
1305 return true;
1308 bool test_qmulz(testspec_t* t, FILE* ofp) {
1309 mp_rat in[3], out[1];
1310 mp_result expect;
1312 ACHECK(parse_rat_values(t, in, out, &expect));
1314 if (!mp_rat_is_integer(in[1])) {
1315 fprintf(stderr,
1316 "Line %d: Second argument must be an integer (test_qmulz)\n",
1317 t->line);
1318 FAIL(MP_BADARG);
1321 ECHECK(mp_rat_mul_int(in[0], MP_NUMER_P(in[1]), in[2]));
1323 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1324 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1325 FAIL(OTHER_ERROR);
1327 return true;
1330 bool test_qdivz(testspec_t* t, FILE* ofp) {
1331 mp_rat in[3], out[1];
1332 mp_result expect;
1334 ACHECK(parse_rat_values(t, in, out, &expect));
1336 if (!mp_rat_is_integer(in[1])) {
1337 fprintf(stderr,
1338 "Line %d: Second argument must be an integer (test_qdivz)\n",
1339 t->line);
1340 FAIL(MP_BADARG);
1343 ECHECK(mp_rat_div_int(in[0], MP_NUMER_P(in[1]), in[2]));
1345 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1346 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1347 FAIL(OTHER_ERROR);
1349 return true;
1352 bool test_qexpt(testspec_t* t, FILE* ofp) {
1353 mp_rat in[3], out[1];
1354 mp_result expect;
1355 mp_small power;
1357 ACHECK(parse_rat_values(t, in, out, &expect));
1359 if (!mp_rat_is_integer(in[1])) {
1360 fprintf(stderr,
1361 "Line %d: Second argument must be an integer (test_qexpt)\n",
1362 t->line);
1363 FAIL(MP_BADARG);
1366 CHECK(mp_int_to_int(MP_NUMER_P(in[1]), &power));
1367 ECHECK(mp_rat_expt(in[0], power, in[2]));
1369 if (expect == MP_OK && mp_rat_compare(in[2], out[0]) != 0) {
1370 mp_rat_to_string(in[2], 10, g_output, OUTPUT_LIMIT);
1371 FAIL(OTHER_ERROR);
1373 return true;
1376 bool test_qtostr(testspec_t* t, FILE* ofp) {
1377 mp_rat in[2];
1378 long radix;
1379 mp_result len;
1381 ACHECK(parse_rat_values(t, in, NULL, NULL));
1382 trim_line(t->input[1]);
1383 ACHECK(read_long(&radix, t->input[1]));
1385 if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) {
1386 fprintf(stderr, "Line %d: Radix %ld out of range\n", t->line, radix);
1387 FAIL(MP_RANGE);
1390 trim_line(t->output[0]);
1391 len = mp_rat_string_len(in[0], radix);
1393 CHECK(mp_rat_to_string(in[0], radix, g_output, len));
1395 if (strcmp(t->output[0], g_output) != 0) FAIL(OTHER_ERROR);
1397 return true;
1400 bool test_qtodec(testspec_t* t, FILE* ofp) {
1401 mp_rat in[4];
1402 long radix, prec, m;
1403 mp_round_mode rmode;
1404 mp_result res, expect = MP_OK, len;
1406 ACHECK(parse_rat_values(t, in, NULL, NULL));
1408 if (t->output[0][0] == '$' && !parse_result_code(t->output[0], &expect)) {
1409 fprintf(stderr, "Line %d: Invalid result code [%s]\n", t->line,
1410 t->output[0]);
1411 FAIL(OTHER_ERROR);
1414 trim_line(t->input[1]);
1415 trim_line(t->input[2]);
1416 trim_line(t->input[3]);
1417 ACHECK(read_long(&radix, t->input[1]));
1418 ACHECK(read_long(&prec, t->input[2]));
1419 ACHECK(read_long(&m, t->input[3]));
1420 rmode = (mp_round_mode)m;
1422 if (prec < 0) {
1423 fprintf(stderr, "Line %d: Precision %ld out of range\n", t->line, prec);
1424 FAIL(MP_RANGE);
1427 trim_line(t->output[0]);
1428 len = mp_rat_decimal_len(in[0], radix, prec);
1429 ECHECK((res = mp_rat_to_decimal(in[0], radix, prec, rmode, g_output, len)));
1431 if (res == MP_OK && strcmp(t->output[0], g_output) != 0) FAIL(OTHER_ERROR);
1433 return true;
1436 bool test_qrdec(testspec_t* t, FILE* ofp) {
1437 mp_rat out[1] = {NULL}, reg = g_qreg + 1;
1438 long radix;
1439 mp_result expect;
1441 ACHECK(parse_rat_values(t, NULL, out, &expect));
1442 trim_line(t->input[1]);
1443 ACHECK(read_long(&radix, t->input[1]));
1445 ECHECK(mp_rat_read_decimal(reg, radix, t->input[0]));
1446 if (expect == MP_OK && mp_rat_compare(reg, out[0]) != 0) {
1447 mp_rat_to_string(reg, 10, g_output, OUTPUT_LIMIT);
1448 FAIL(OTHER_ERROR);
1450 return true;
1453 bool test_is_prime(testspec_t* t, FILE* OFP) {
1454 mp_int in[1] = {NULL};
1455 mp_result expect;
1457 ACHECK(parse_int_values(t, in, NULL, &expect));
1458 ECHECK(mp_int_is_prime(in[0]));
1459 return true;
1462 /* Here there be dragons */