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: .SUFFIXES:
.PHONY: all .PHONY: all
all: true false cat env hexdump all: true false cat env hexdump echo
#all: echo
%: %.o %: %.o
$(LD) -o $@ $(filter %.o, $^) $(LD) -o $@ $(filter %.o, $^)
@ -20,3 +19,4 @@ sorttest: lib/sort.o
.PHONY: test .PHONY: test
test: test:
@BIN=. test/true.sh @BIN=. test/true.sh
@BIN=. test/echo.sh

33
echo.s
View File

@ -3,15 +3,14 @@
.option norelax .option norelax
.section .rodata .section .rodata
space_or_newline: space: .ascii " "
.ascii " ", "\n" newline: .ascii "\n"
.text .text
_start: _start:
# arguments are passed on the stack: # arguments are passed on the stack:
# --bottom of stack-- # --bottom of stack--
# dd argc # dd argc
# dd argv
# dd argv[0] # dd argv[0]
# dd ... # dd ...
# dd 0 # dd 0
@ -19,7 +18,6 @@ _start:
# dd ... # dd ...
# dd 0 # dd 0
ld s0, 0(sp) # get argc ld s0, 0(sp) # get argc
#ld s1, 8(sp) # get argv
add s1, sp, 8 add s1, sp, 8
# TODO: iovec # TODO: iovec
@ -38,6 +36,7 @@ _start:
# write each argument # write each argument
li s11, 0 li s11, 0
mv s2, s0 mv s2, s0
la s8, space
loop: loop:
# get argv[i] # get argv[i]
slli t0, s11, 3 slli t0, s11, 3
@ -61,21 +60,20 @@ loop:
ecall ecall
bltz a0, write_error bltz a0, write_error
# if not the last argument, print a space # increment index
# otherwise print a newline # if this was the last argument, break
# addi s11, s11, 1
# a1 = space_or_newline + (argc-s11 < 2) bge s11, s0, end
la a1, space_or_newline
sub t0, s0, s11
sltiu t0, t0, 2
add a1, a1, t0
# not the last argument, so print a space and loop
li a7, 64 # sys_write li a7, 64 # sys_write
li a0, 1 # stdout li a0, 1 # stdout
#la a1, newline or space mv a1, s8 # space
li a2, 1 # size li a2, 1 # size
ecall ecall
bltz a0, write_error bltz a0, write_error
j loop
step: step:
# increment index and loop # increment index and loop
@ -83,6 +81,15 @@ step:
blt s11, s0, loop blt s11, s0, loop
end: 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 a7, 93 # exit
li a0, 0 li a0, 0
ecall 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 -eu
set -o pipefail set -o pipefail
: ${BIN:-..} : ${BIN:=..}
: ${EMU:=qemu-riscv64} : ${EMU:=qemu-riscv64}
cmd=$BIN/true cmd=$BIN/true