summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2019-08-04 14:21:05 +1200
committerDavid Phillips <david@sighup.nz>2019-08-04 14:24:50 +1200
commit4b1f9e2cb436e74ce6084dbc35df5f052cb701bf (patch)
tree201bf4d3cf1120ad0e9a8d3fe7b1a95c2fd3333d
parent1c8e50028e15facaa4d31992bfc6cab9d10832e6 (diff)
downloadtoy-cpu-assembler-4b1f9e2cb436e74ce6084dbc35df5f052cb701bf.tar.xz
Wrap tests in valgrind, clean up memory leaks
-rw-r--r--Makefile2
-rw-r--r--assembler.c5
-rw-r--r--disassembler.c4
-rw-r--r--lex.c18
-rw-r--r--lex.h1
-rw-r--r--parse.c16
-rw-r--r--parse.h1
-rwxr-xr-xtest/emul/run-emul.sh42
-rwxr-xr-xtest/full-pipeline/run-full-pipeline.sh7
-rw-r--r--test/valgrind.sh2
10 files changed, 74 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index 99d04ae..e3cb8e5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
EXECUTABLES = assembler disassembler emulator asmcat bincat
ASM_OBJECTS = assembler.o lex.o parse.o output/output_bin.o util.o
-DISASM_OBJECTS = disassembler.o input/input_bin.o output/output_asm.o util.o
+DISASM_OBJECTS = disassembler.o input/input_bin.o output/output_asm.o parse.o util.o
EMUL_OBJECTS = input/input_bin.o util.o
ASMCAT_OBJECTS = asmcat.o lex.o parse.o output/output_asm.o util.o
BINCAT_OBJECTS = bincat.o input/input_bin.o output/output_bin.o util.o
diff --git a/assembler.c b/assembler.c
index 7ae699d..bd94c33 100644
--- a/assembler.c
+++ b/assembler.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@@ -63,6 +64,7 @@ int main(int argc, char **argv)
if ((tokens = lex(path_in, fin, &tok_count)) == NULL)
return error_ret;
+ fclose(fin);
debug("Lexed.\n");
/* FIXME package these things into `tok_result`, `parse_result` etc */
@@ -82,6 +84,9 @@ int main(int argc, char **argv)
if ((ret = output_bin(fout, labels, labels_count, insts, insts_count)))
return error_ret && ret;
+ parse_free(insts, insts_count, labels, labels_count);
+ lex_free(tokens, tok_count);
+ fclose(fout);
debug("Output.\n");
return 0;
diff --git a/disassembler.c b/disassembler.c
index 8da5a38..26f0b79 100644
--- a/disassembler.c
+++ b/disassembler.c
@@ -64,8 +64,12 @@ int main(int argc, char **argv)
if ((ret = input_bin(fin, &insts, &insts_count)))
return error_ret && ret;
+ fclose(fin);
+
if ((ret = output_asm(fout, labels, labels_count, insts, insts_count)))
return error_ret && ret;
+ parse_free(insts, insts_count, NULL, 0);
+ fclose(fout);
return 0;
}
diff --git a/lex.c b/lex.c
index 949425e..6ed8007 100644
--- a/lex.c
+++ b/lex.c
@@ -380,6 +380,24 @@ int lex_line(void) {
return 0;
}
+void lex_free_tok(struct token t)
+{
+ if (t.s_val)
+ free(t.s_val);
+
+}
+
+void lex_free(struct token *ts, size_t t_count)
+{
+ size_t i = 0;
+
+ for (i = 0; i < t_count; i++) {
+ lex_free_tok(ts[i]);
+ }
+
+ free(ts);
+}
+
struct token* lex(const char *filename_local, FILE *fin, size_t *len)
{
filename = filename_local;
diff --git a/lex.h b/lex.h
index a14528f..908d23e 100644
--- a/lex.h
+++ b/lex.h
@@ -26,5 +26,6 @@ struct token {
};
struct token* lex(const char *filename_local, FILE *fin, size_t *len);
+void lex_free(struct token *ts, size_t t_count);
#endif /* LEX_H */
diff --git a/parse.c b/parse.c
index 45758c9..2bfc7da 100644
--- a/parse.c
+++ b/parse.c
@@ -471,6 +471,22 @@ int parse_instruction(void)
return 1;
}
+void parse_free_l(struct label l)
+{
+ free(l.name);
+}
+
+void parse_free(struct instruction *is, size_t i_count, struct label *ls, size_t l_count)
+{
+ size_t i = 0;
+
+ for (i = 0; i < l_count; i++) {
+ parse_free_l(ls[i]);
+ }
+ free(ls);
+ free(is);
+}
+
int parse(const char *filename_local, FILE* fd_local, struct label **labels_local, size_t *labels_count_local, struct token *tokens_local, size_t tokens_count_local, struct instruction **instructions, size_t *instructions_count)
{
int ret = 0;
diff --git a/parse.h b/parse.h
index 5feb420..d5fc466 100644
--- a/parse.h
+++ b/parse.h
@@ -61,5 +61,6 @@ struct instruction {
};
int parse(const char *filename_local, FILE *fd, struct label **labels_local, size_t *labels_count_local, struct token *tokens, size_t tokens_count, struct instruction **instructions, size_t *instructions_count);
+void parse_free(struct instruction *is, size_t i_count, struct label *ls, size_t l_count);
#endif /* PARSE_H */
diff --git a/test/emul/run-emul.sh b/test/emul/run-emul.sh
index 496f13d..2db56f3 100755
--- a/test/emul/run-emul.sh
+++ b/test/emul/run-emul.sh
@@ -23,6 +23,7 @@ clean() {
WORK=$(mktemp -d)
pushd $(dirname "$0") >/dev/null
+source ../valgrind.sh
export ASM="$PWD/../../assembler"
export EMUL="$PWD/../../emulator"
has_failure=0
@@ -36,26 +37,27 @@ for asmfile in *.asm ; do
continue
fi
- "$EMUL" "$binfile" > "$outfile"
-
- # Each postcondition line must hold true, and forms a separate test to
- # help track down failures
- (echo '; POST $0 = 0' ;
- echo '; POST $H = 0xFFFF' ;
- grep '^;\s\+POST\s\+' "$asmfile" ) | while read line ; do
- reg=$(awk -F= '{print $1}' <<< "$line" | awk '{print $(NF)}')
- val=$(awk -F= '{print $2}' <<< "$line"| awk '{print $1}')
- subtest="${asmfile}:${reg}"
- # Scrape output of emulator for register value
- actual=$(grep "$reg" "$outfile" | awk '{print $2}')
- if [[ "$actual" -eq "$val" ]]; then
- pass "$subtest"
- else
- fail "$subtest" "postcondition (expect $val, got $actual)"
- has_failure=1
- fi
- done
-
+ if "$VALGRIND" $VALGRIND_OPTS "$EMUL" "$binfile" > "$outfile" ; then
+ # Each postcondition line must hold true, and forms a separate test to
+ # help track down failures
+ (echo '; POST $0 = 0' ;
+ echo '; POST $H = 0xFFFF' ;
+ grep '^;\s\+POST\s\+' "$asmfile" ) | while read line ; do
+ reg=$(awk -F= '{print $1}' <<< "$line" | awk '{print $(NF)}')
+ val=$(awk -F= '{print $2}' <<< "$line"| awk '{print $1}')
+ subtest="${asmfile}:${reg}"
+ # Scrape output of emulator for register value
+ actual=$(grep "$reg" "$outfile" | awk '{print $2}')
+ if [[ "$actual" -eq "$val" ]]; then
+ pass "$subtest"
+ else
+ fail "$subtest" "postcondition (expect $val, got $actual)"
+ has_failure=1
+ fi
+ done
+ else
+ fail "$asmfile" "non-zero exit code"
+ fi
done
popd >/dev/null
diff --git a/test/full-pipeline/run-full-pipeline.sh b/test/full-pipeline/run-full-pipeline.sh
index aeb7c4f..cfa149f 100755
--- a/test/full-pipeline/run-full-pipeline.sh
+++ b/test/full-pipeline/run-full-pipeline.sh
@@ -29,6 +29,7 @@ else
fi
WORK=$(mktemp -d)
pushd $(dirname "$0") >/dev/null
+source ../valgrind.sh
export ASM="$PWD/../../assembler"
export DISASM="$PWD/../../disassembler"
has_failure=0
@@ -39,17 +40,17 @@ for first_stage_asm in *.asm ; do
second_stage_bin="$WORK/${first_stage_asm}-second_stage.bin"
# Assemble test code
- if ! "$ASM" "$first_stage_asm" "$first_stage_bin" ; then
+ if ! "$VALGRIND" $VALGRIND_OPTS "$ASM" "$first_stage_asm" "$first_stage_bin" ; then
fail "$first_stage_asm" "first stage assembly failed"
continue
fi
# Disassemble test code and re-assemble that disassembly
- if ! "$DISASM" "$first_stage_bin" "$second_stage_asm" ; then
+ if ! "$VALGRIND" $VALGRIND_OPTS "$DISASM" "$first_stage_bin" "$second_stage_asm" ; then
fail "$first_stage_asm" "first stage disassembly failed"
continue
fi
- if ! "$ASM" "$second_stage_asm" "$second_stage_bin" ; then
+ if ! "$VALGRIND" $VALGRIND_OPTS "$ASM" "$second_stage_asm" "$second_stage_bin" ; then
fail "$first_stage_asm" "second stage assembly failed"
continue
fi
diff --git a/test/valgrind.sh b/test/valgrind.sh
new file mode 100644
index 0000000..9c230d4
--- /dev/null
+++ b/test/valgrind.sh
@@ -0,0 +1,2 @@
+VALGRIND=valgrind
+VALGRIND_OPTS="-q --error-exitcode=1 --leak-check=full --show-reachable=yes"