echo: print newline even with no args, and add some tests

This commit is contained in:
magical 2023-04-24 23:24:38 -07:00
parent d49a5c9edc
commit 2ecbb120e2
4 changed files with 79 additions and 16 deletions

View File

@ -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
View File

@ -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
View 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

View File

@ -2,7 +2,7 @@
set -eu
set -o pipefail
: ${BIN:-..}
: ${BIN:=..}
: ${EMU:=qemu-riscv64}
cmd=$BIN/true