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:
|
.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
33
echo.s
@ -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
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 -eu
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
: ${BIN:-..}
|
: ${BIN:=..}
|
||||||
: ${EMU:=qemu-riscv64}
|
: ${EMU:=qemu-riscv64}
|
||||||
|
|
||||||
cmd=$BIN/true
|
cmd=$BIN/true
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user