|
|
1.1 root 1: /*
2: * nono
3: * Copyright (C) 2021 nono project
4: * Licensed under nono-license.txt
5: */
6:
7: #include "optestm88k_main.h"
8: #include <setjmp.h>
9: #include <signal.h>
10: #include <stdlib.h>
11: #include <sys/siginfo.h>
12:
13: // グローバルワーク (r2 でアセンブラに渡される)
14: int global_work[2];
15:
16: // オーバーフロー例外なら 1、除算例外なら 2 をセットする。
17: // テスト前に 0 で初期化しておくこと。
18: #define exception_occurred (global_work[0])
19: // 例外を期待するなら 1 か 2、期待しないなら 0 (テスト側が書く)
20: #define exception_expected (global_work[1])
21:
22: static void
23: sigfpe(int signo, siginfo_t *si, void *ctx)
24: {
25: if (si->si_signo == SIGFPE) {
26: if (si->si_code == FPE_INTOVF) {
27: exception_occurred = 1;
28: return;
29: } else if (si->si_code == FPE_INTDIV) {
30: exception_occurred = 2;
31: return;
32: }
33: }
34: // XXX
35: exception_occurred = -1;
36: }
37:
38: int
39: main(int ac, char *av[])
40: {
41: char cause[64];
42: struct testentry *t;
43: func_t func;
44: const char *arg_name = "";
45: int i;
46: int j;
47: int num;
48: int res;
49:
50: if (ac >= 2) {
51: arg_name = av[1];
52: }
53:
54: struct sigaction act;
55: memset(&act, 0, sizeof(act));
56: act.sa_sigaction = sigfpe;
57: act.sa_flags = SA_SIGINFO;
58: sigaction(SIGFPE, &act, NULL);
59:
60: for (i = j = 0; test_table[i].code != NULL; i++, j = 0) {
61: t = &test_table[i];
62:
63: if (strncasecmp(t->testname, arg_name, strlen(arg_name)) != 0) {
64: break;
65: }
66:
67: if (j == 0) {
68: // テスト数を数える
69: for (num = 0; t->testdata[num] != NULL; num++)
70: ;
71:
72: printf("%s (%d) ... ", t->testname, num);
73: fflush(stdout);
74: }
75:
76: for (; j < num; j++) {
77: exception_occurred = 0;
78:
79: res = (t->code)(global_work, t->testdata[j]);
80: // 失敗なら非 0 を返す
81: // bit3 は演算結果が期待と異なる
82: // bit0 は例外有無が期待と異なる
83: if (res != 0) {
84: cause[0] = '\0';
85: if ((res & 8)) {
86: strlcpy(cause, "incorrect result", sizeof(cause));
87: }
88: if ((res & 1)) {
89: if (cause[0]) {
90: strlcat(cause, ", ", sizeof(cause));
91: }
92: if (exception_expected) {
93: // 例外を期待したが、例外が起きなかった。
94: strlcat(cause, "exception not occurred", sizeof(cause));
95: } else {
96: // 例外が起きないことを期待したのに例外が起きた。
97: strlcat(cause, "exception occurred", sizeof(cause));
98: }
99: }
100: printf("FAILED (%s) at test_%s_%d\n",
101: cause, t->testname, j);
102: exit(1);
103: }
104: }
105:
106: printf("ok\n");
107: }
108:
109: return 0;
110: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.