echo: print newline even with no args, and add some tests
This commit is contained in:
parent
d49a5c9edc
commit
2ecbb120e2
4
Makefile
4
Makefile
@ -5,8 +5,7 @@ LD = $(TARGET)-ld
|
||||
.SUFFIXES:
|
||||
|
||||
.PHONY: all
|
||||
all: true false cat env hexdump
|
||||
#all: echo
|
||||
all: true false cat env hexdump echo
|
||||
|
||||
%: %.o
|
||||
$(LD) -o $@ $(filter %.o, $^)
|
||||
@ -20,3 +19,4 @@ sorttest: lib/sort.o
|
||||
.PHONY: test
|
||||
test:
|
||||
@BIN=. test/true.sh
|
||||
@BIN=. test/echo.sh
|
||||
|
||||
33
echo.s
33
echo.s
@ -3,15 +3,14 @@
|
||||
.option norelax
|
||||
|
||||
.section .rodata
|
||||
space_or_newline:
|
||||
.ascii " ", "\n"
|
||||
space: .ascii " "
|
||||
newline: .ascii "\n"
|
||||
|
||||
.text
|
||||
_start:
|
||||
# arguments are passed on the stack:
|
||||
# --bottom of stack--
|
||||
# dd argc
|
||||
# dd argv
|
||||
# dd argv[0]
|
||||
# dd ...
|
||||
# dd 0
|
||||
@ -19,7 +18,6 @@ _start:
|
||||
# dd ...
|
||||
# dd 0
|
||||
ld s0, 0(sp) # get argc
|
||||
#ld s1, 8(sp) # get argv
|
||||
add s1, sp, 8
|
||||
|
||||
# TODO: iovec
|
||||
@ -38,6 +36,7 @@ _start:
|
||||
# write each argument
|
||||
li s11, 0
|
||||
mv s2, s0
|
||||
la s8, space
|
||||
loop:
|
||||
# get argv[i]
|
||||
slli t0, s11, 3
|
||||
@ -61,21 +60,20 @@ loop:
|
||||
ecall
|
||||
bltz a0, write_error
|
||||
|
||||
# if not the last argument, print a space
|
||||
# otherwise print a newline
|
||||
#
|
||||
# a1 = space_or_newline + (argc-s11 < 2)
|
||||
la a1, space_or_newline
|
||||
sub t0, s0, s11
|
||||
sltiu t0, t0, 2
|
||||
add a1, a1, t0
|
||||
# increment index
|
||||
# if this was the last argument, break
|
||||
addi s11, s11, 1
|
||||
bge s11, s0, end
|
||||
|
||||
# not the last argument, so print a space and loop
|
||||
li a7, 64 # sys_write
|
||||
li a0, 1 # stdout
|
||||
#la a1, newline or space
|
||||
mv a1, s8 # space
|
||||
li a2, 1 # size
|
||||
ecall
|
||||
|
||||
bltz a0, write_error
|
||||
j loop
|
||||
|
||||
step:
|
||||
# increment index and loop
|
||||
@ -83,6 +81,15 @@ step:
|
||||
blt s11, s0, loop
|
||||
|
||||
end:
|
||||
# print a newline at the end,
|
||||
# regardless of whether there were any arguments or not
|
||||
li a7, 64 # sys_write
|
||||
li a0, 1 # stdout
|
||||
la a1, newline
|
||||
li a2, 1 # size
|
||||
ecall
|
||||
bltz a0, write_error
|
||||
|
||||
li a7, 93 # exit
|
||||
li a0, 0
|
||||
ecall
|
||||
|
||||
56
test/echo.sh
Executable file
56
test/echo.sh
Executable file
@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
: ${BIN:=..}
|
||||
: ${EMU:=qemu-riscv64}
|
||||
|
||||
cmd=$BIN/echo
|
||||
name=echo
|
||||
|
||||
fail=0
|
||||
err() {
|
||||
echo "FAIL $name: $*"
|
||||
fail=1
|
||||
}
|
||||
|
||||
# the shell strips the trailing newline when capturing output,
|
||||
# which makes writing tests for echo a bit difficult
|
||||
|
||||
out=$($EMU $cmd)
|
||||
len=$($EMU $cmd | wc -c)
|
||||
stat=$?
|
||||
if [ "$out" != "" ]; then
|
||||
err "expected a newline"
|
||||
fi
|
||||
if [ "$len" -ne 1 ]; then
|
||||
err "expected len 1, got len $len"
|
||||
fi
|
||||
if [ "$stat" -ne 0 ]; then
|
||||
err "exited with status code $stat, expected 0"
|
||||
fi
|
||||
|
||||
|
||||
out=$($EMU $cmd a b c)
|
||||
stat=$?
|
||||
if [ "$out" != "a b c" ]; then
|
||||
err "expected 'a b c', got '$out'"
|
||||
fi
|
||||
if [ "$stat" -ne 0 ]; then
|
||||
err "exited with status code $stat, expected 0"
|
||||
fi
|
||||
|
||||
|
||||
out=$($EMU $cmd 'a b')
|
||||
stat=$?
|
||||
if [ "$out" != "a b" ]; then
|
||||
err "expected 'a b', got '$out'"
|
||||
fi
|
||||
if [ "$stat" -ne 0 ]; then
|
||||
err "exited with status code $stat, expected 0"
|
||||
fi
|
||||
|
||||
|
||||
if [ "$fail" -eq 0 ]; then
|
||||
echo PASS $name
|
||||
fi
|
||||
@ -2,7 +2,7 @@
|
||||
set -eu
|
||||
set -o pipefail
|
||||
|
||||
: ${BIN:-..}
|
||||
: ${BIN:=..}
|
||||
: ${EMU:=qemu-riscv64}
|
||||
|
||||
cmd=$BIN/true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user