From 3b279e25af793206ca3b0c37b2a77f75939e7db8 Mon Sep 17 00:00:00 2001 From: lexzach Date: Sun, 13 Sep 2026 15:47:54 -0400 Subject: [PATCH] Add help --- src/args.S | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/file.S | 2 +- src/main.S | 30 ++++++++++++++++- 3 files changed, 124 insertions(+), 5 deletions(-) diff --git a/src/args.S b/src/args.S index 9662678..5c24494 100644 --- a/src/args.S +++ b/src/args.S @@ -1,10 +1,8 @@ .data sp_start: .space 8 -flag_h: .asciz "-h" -flag_helpo: .asciz "--help" .section .text -.globl save_sp, fetch_argc, fetch_argv +.globl save_sp, fetch_argc, fetch_argv, has_switch save_sp: sd sp, sp_start, t0 # save the stack pointer @@ -94,6 +92,99 @@ fetch_argv: addi sp, sp, 8 ret +# Check if flag was given +# @param[in] a0: ptr to null-terminated switch 1 (ie. -h). +# @param[in] a1: ptr to null-terminated switch 2 (ie. --help) (optional). +# @param[out] a0: result code. +# @param[out] a1: was found (0-not found, 1-found). +has_switch: + addi sp, sp, -24 # store ra and s regs to stack + sd ra, 16(sp) + sd s1, 8(sp) + sd s0, 0(sp) + + mv s0, a0 + mv s1, a1 + + call fetch_argc + bnez a0, 1f + li t0, 2 + blt a1, t0, 1f # if we have no commands other than the binary, we know there will be no switches + + addi sp, sp, -24 + sd s4, 16(sp) + sd s2, 8(sp) + sd s3, 0(sp) + li s2, 1 # load first non-base command arg + mv s4, a1 # put argc in s4 + + 2: + mv a0, s2 + call fetch_argv + mv s3, a1 # save argv buff addr + + mv a0, s3 # load argv buff addr into a0 (string 0) + mv a1, s0 # move switch ptr 1 addr into a1 (string 1) + call _str_cmp + bnez a1, 5f # if the strings match, exit loop + + mv a0, s3 # move argv buff addr into a0 (string 0) + mv a1, s1 # move switch ptr 2 addr into a1 (string 1) + call _str_cmp + bnez a1, 5f # if the strings match, exit loop + + addi s2, s2, 1 # if string doesn't match we inc to the next arg + blt s2, s4, 2b # keep going while we have untested args + + 4: + li a0, 0 + li a1, 0 + j 3f + + 5: + li a0, 0 + li a1, 1 + + 3: + ld s3, 0(sp) + ld s2, 8(sp) + ld s4, 16(sp) + addi sp, sp, 24 + + 1: + ld ra, 16(sp) + ld s1, 8(sp) + ld s0, 0(sp) + addi sp, sp, 24 # restore ra and s regs from stack + ret + +# Compares two null terminated string buffers. +# @param[in] a0: str buffer 1 +# @param[in] a1: str buffer 2 +# @param[out] a0: result code. +# @param[out] a1: is equal (0-no, 1-yes). +_str_cmp: + li t2, 0 + + 1: + add t0, a0, t2 + add t1, a1, t2 + lb t0, 0(t0) + lb t1, 0(t1) + bne t0, t1, 3f # first byte that isn't the same, branch to no match + beqz t0, 2f # jump to ret when null is read + addi t2, t2, 1 + j 1b + + 3: # no match + li a0, 0 + li a1, 0 + ret + + 2: # match + li a0, 0 + li a1, 1 + ret # Fetch argument value # @param[in] a0: address of current argv. diff --git a/src/file.S b/src/file.S index eb9de7c..deb9265 100644 --- a/src/file.S +++ b/src/file.S @@ -2,7 +2,7 @@ cat_buf: .space 4096 .section .text -.globl cat_file, open_fd, file_exists +.globl cat_file, open_fd # Cat out the given file to stdout # @param[in] a0: ptr to null-terminated file str. diff --git a/src/main.S b/src/main.S index 01625f7..71c07fb 100644 --- a/src/main.S +++ b/src/main.S @@ -1,10 +1,20 @@ .data argc: .space 8 + cat_prefix: .asciz "cat: " .equ CAT_PREFIX_LEN, . - cat_prefix + file_err: .asciz ": No such file or directory\n" .equ FILE_ERR_LEN, . - file_err +help: .asciz "Usage: cat [OPTION]... [FILE]...\nConcatenate FILE(S) to standard output.\n" +.equ HELP_LEN, . - help + +flag_h: .asciz "-h" +# .equ FLAG_H_LEN, . - flag_h +flag_help: .asciz "--help" +# .equ FLAG_HELP_LEN, . - flag_help + .section .text .globl _start @@ -18,10 +28,20 @@ _start: call save_sp call fetch_argc li t0, 1 - ble a1, t0, 1f # return 1 if no file given + ble a1, t0, 1f # return 1 if no args mv s0, a1 # store argc li s1, 1 + la a0, flag_h + la a1, flag_help + call has_switch + bnez a0, 1f + beqz a1, .Lskip_disp_help + call _disp_help + j 2f + .Lskip_disp_help: + + # 5: #iterate through and check that all files exist first # mv a0, s1 # call fetch_argv @@ -75,3 +95,11 @@ _start: li a0, 0 li a7, 93 ecall # return 0 + +_disp_help: + la a0, 1 + la a1, help + li a2, HELP_LEN + li a7, 64 + ecall + ret