> compile NEMU
ysyx_22040000 李心杨 Linux calcite 6.1.69 #1-NixOS SMP PREEMPT_DYNAMIC Wed Dec 20 16:00:29 UTC 2023 x86_64 GNU/Linux 02:55:41 up 1 day 3:11, 2 users, load average: 0.95, 0.77, 0.65
This commit is contained in:
parent
70ec0a166a
commit
b97e2bf469
4 changed files with 60 additions and 43 deletions
|
@ -63,6 +63,7 @@ endif
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|
||||||
include $(NEMU_HOME)/tests/Makefile
|
include $(NEMU_HOME)/tests/Makefile
|
||||||
|
all-tests: TEST_OBJS = $(filter-out $(OBJ_DIR)/src/nemu-main.o, $(OBJS))
|
||||||
all-tests: CFLAGS += $(shell pkg-config --cflags check)
|
all-tests: CFLAGS += $(shell pkg-config --cflags check)
|
||||||
all-tests: LDFLAGS += $(shell pkg-config --libs check)
|
all-tests: LDFLAGS += $(shell pkg-config --libs check)
|
||||||
all-tests: $(TEST_SRCS:%.c=$(OBJ_DIR)/%)
|
all-tests: $(TEST_SRCS:%.c=$(OBJ_DIR)/%)
|
||||||
|
|
|
@ -21,13 +21,13 @@ input
|
||||||
;
|
;
|
||||||
|
|
||||||
expression
|
expression
|
||||||
: expression '+' expression { $$ = $1 + $3; }
|
: number { $$ = $1; }
|
||||||
|
| expression '+' expression { $$ = $1 + $3; }
|
||||||
| expression '-' expression { $$ = $1 - $3; }
|
| expression '-' expression { $$ = $1 - $3; }
|
||||||
| expression '*' expression { $$ = $1 * $3; }
|
| expression '*' expression { $$ = $1 * $3; }
|
||||||
| expression '/' expression { $$ = $1 / $3; }
|
| expression '/' expression { $$ = $1 / $3; }
|
||||||
| '-' number { $$ = -$2; }
|
| '-' number { $$ = -$2; }
|
||||||
| '(' expression ')' { $$ = $2; }
|
| '(' expression ')' { $$ = $2; }
|
||||||
| number { $$ = $1; }
|
|
||||||
|
|
||||||
number
|
number
|
||||||
: NUMBER
|
: NUMBER
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
TEST_SRCS += tests/expr_test.c
|
TEST_SRCS += tests/expr_test.c
|
||||||
|
|
||||||
$(OBJ_DIR)/%: %.c $(OBJS)
|
$(OBJ_DIR)/%: %.c $(TEST_OBJS) app
|
||||||
@echo + CC $<
|
@echo + CC $<
|
||||||
@$(CC) $(CFLAGS) -Wl,-e,test_main -o $@ $^ $(LIBS) $(LDFLAGS) $(CFLGAS)
|
@$(CC) $(CFLAGS) -o $@.o -c $<
|
||||||
|
@echo + LD $@
|
||||||
|
@$(LD) $(LIBS) $(LDFLAGS) -o $@ $(TEST_OBJS) $@.o
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "sys/types.h"
|
#include "sys/types.h"
|
||||||
|
#include "unistd.h"
|
||||||
#include <check.h>
|
#include <check.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -8,30 +9,37 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
char buf[65536] = "python3 -c print(";
|
char buf[65536] = {};
|
||||||
char *buf_ptr = buf + 17;
|
static char code_buf[65536 + 128] = {}; // a little larger than `buf`
|
||||||
|
const int buf_start_pos = 0;
|
||||||
|
char *buf_ptr = buf + buf_start_pos;
|
||||||
|
static char *code_format =
|
||||||
|
"#include <stdio.h>\n"
|
||||||
|
"#include <stdint.h>\n"
|
||||||
|
"int main() { "
|
||||||
|
" uint32_t result = %s; "
|
||||||
|
" printf(\"%%u\", result); "
|
||||||
|
" return 0; "
|
||||||
|
"}";
|
||||||
|
|
||||||
|
|
||||||
void gen(char c) {
|
void gen(char c) {
|
||||||
*(buf_ptr++) = c;
|
*(buf_ptr++) = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_num(void) {
|
void gen_num(void) {
|
||||||
int len = rand() % 8 + 1;
|
uint32_t num = rand() % 100000;
|
||||||
int base = 10;
|
int len = 0;
|
||||||
switch(rand() % 2) {
|
switch(rand() % 2) {
|
||||||
case 0: base = 10; break;
|
case 0:
|
||||||
case 1: base = 16; break;
|
len = snprintf(buf_ptr, 100, "%u", num);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
len = snprintf(buf_ptr, 100, "0x%x", num);
|
||||||
|
break;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
const char *strmap = "0123456789abcdef";
|
buf_ptr += len;
|
||||||
// TODO: add minus
|
|
||||||
if (base == 16) {
|
|
||||||
gen('0');
|
|
||||||
gen('x');
|
|
||||||
}
|
|
||||||
while(len--) {
|
|
||||||
gen(strmap[rand() % base]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_rand_op(void) {
|
void gen_rand_op(void) {
|
||||||
|
@ -50,32 +58,40 @@ void gen_rand_expr(void) {
|
||||||
case 1: gen('('); gen_rand_expr(); gen(')'); break;
|
case 1: gen('('); gen_rand_expr(); gen(')'); break;
|
||||||
default: gen_rand_expr(); gen_rand_op(); gen_rand_expr(); break;
|
default: gen_rand_expr(); gen_rand_op(); gen_rand_expr(); break;
|
||||||
}
|
}
|
||||||
printf("buf: %s\n", buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
START_TEST(test_test1) {
|
START_TEST(test_expr_random_100) {
|
||||||
for (int i = 0; i < 10; i++) {
|
srand(time(0) + _i * 100);
|
||||||
gen_rand_expr();
|
gen_rand_expr();
|
||||||
yy_scan_string(buf + 18);
|
yy_scan_string(buf + buf_start_pos);
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
ck_assert(!yyparse(&addr));
|
ck_assert(!yyparse(&addr));
|
||||||
yylex_destroy();
|
yylex_destroy();
|
||||||
|
|
||||||
/* Open the command for reading. */
|
sprintf(code_buf, code_format, buf);
|
||||||
FILE *fp;
|
|
||||||
*(buf_ptr++) = ')';
|
FILE *fp = fopen("/tmp/.code.c", "w");
|
||||||
fp = popen(buf, "r");
|
ck_assert(fp != NULL);
|
||||||
|
fputs(code_buf, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
int ret = system("gcc /tmp/.code.c -o /tmp/.expr 2>/dev/null");
|
||||||
|
ck_assert_msg(!ret, "system ret: %d, error: %s", ret, strerror(ret));
|
||||||
|
|
||||||
|
fp = popen("/tmp/.expr", "r");
|
||||||
ck_assert(fp != NULL);
|
ck_assert(fp != NULL);
|
||||||
|
|
||||||
/* Read the output a line at a time - output it. */
|
uint32_t reference;
|
||||||
uint32_t reference = 0;
|
ret = fscanf(fp, "%u", &reference);
|
||||||
ck_assert(fscanf(fp, "%u", &reference) == 0);
|
ck_assert(ret == 1);
|
||||||
ck_assert(addr == reference);
|
pclose(fp);
|
||||||
|
// fprintf(stderr, "\n\tbuf = %s\n\taddr = %u, reference = %u", buf, addr, reference);
|
||||||
|
|
||||||
while(buf_ptr != buf + 18) {
|
ck_assert_msg(addr == reference, "\n\tbuf = %s\n\taddr = %u, reference = %u\n", buf, addr, reference);
|
||||||
|
|
||||||
|
while(buf_ptr != buf + buf_start_pos) {
|
||||||
*(--buf_ptr) = '\0';
|
*(--buf_ptr) = '\0';
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} END_TEST
|
} END_TEST
|
||||||
|
|
||||||
START_TEST(test_test2) {
|
START_TEST(test_test2) {
|
||||||
|
@ -89,18 +105,17 @@ Suite *expr_suite(void) {
|
||||||
s = suite_create("Expr test");
|
s = suite_create("Expr test");
|
||||||
tc_core = tcase_create("Core");
|
tc_core = tcase_create("Core");
|
||||||
|
|
||||||
tcase_add_test(tc_core, test_test1);
|
tcase_add_loop_test(tc_core, test_expr_random_100, 0, 100);
|
||||||
tcase_add_test(tc_core, test_test2);
|
tcase_add_test(tc_core, test_test2);
|
||||||
suite_add_tcase(s, tc_core);
|
suite_add_tcase(s, tc_core);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_main(void) {
|
int main(void) {
|
||||||
int number_failed;
|
int number_failed;
|
||||||
Suite *s;
|
Suite *s;
|
||||||
SRunner *sr;
|
SRunner *sr;
|
||||||
srand(time(0));
|
|
||||||
|
|
||||||
s = expr_suite();
|
s = expr_suite();
|
||||||
sr = srunner_create(s);
|
sr = srunner_create(s);
|
||||||
|
@ -111,4 +126,3 @@ int test_main(void) {
|
||||||
|
|
||||||
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue