From 90b6c515ca0fe027ca68504d26e6892fabdfe6cd Mon Sep 17 00:00:00 2001 From: lexzach Date: Tue, 15 Sep 2026 12:10:33 -0400 Subject: [PATCH 1/3] Start on non-blank line num display --- README.md | 2 ++ src/main.S | 38 +++++++++++++++++++++++++++++--------- src/mod.S | 22 +++++++++++++++++----- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 108deb2..b166d10 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ Run the `make` command in the root of the repository. Options: +`-b, --number-nonblank` - number nonempty output lines, overrides -n `-E, --show-ends` - display $ at end of each line\ +`-n, --number` - number all output lines `--help` - Show the help page.\ `--version` - Show the version page. diff --git a/src/main.S b/src/main.S index 13323f0..af8935d 100644 --- a/src/main.S +++ b/src/main.S @@ -1,7 +1,8 @@ .data -argc: .space 8 -show_ends: .space 1 -number: .space 1 +argc: .space 8 +show_ends: .space 1 +number: .space 1 +number_nonblank: .space 1 cat_prefix: .ascii "cat: " .equ CAT_PREFIX_LEN, . - cat_prefix @@ -13,15 +14,16 @@ help: .ascii "Usage: cat [OPTION]... [FILE]...\n" .ascii "Concatenate FILE(S) to standard output.\n\n" .ascii "With no FILE, or when FILE is -, read standard input.\n\n" - .ascii " -E, --show-ends display $ at end of each line\n" - .ascii " -n, --number number all output lines\n" - .ascii " --help display this help and exit\n" - .ascii " --version output version information and exit\n\n" + .ascii " -b, --number-nonblank number nonempty output lines, overrides -n\n" + .ascii " -E, --show-ends display $ at end of each line\n" + .ascii " -n, --number number all output lines\n" + .ascii " --help display this help and exit\n" + .ascii " --version output version information and exit\n\n" .asciz "Git repository: \n" .equ HELP_LEN, . - help version: - .ascii "cat 1.3.0\n" + .ascii "cat 1.4.0\n" .ascii "Copyright (C) 2026 lexzach\n" .ascii "License MIT\n" .ascii "This is free software: you are free to change and redistribute it.\n" @@ -35,9 +37,11 @@ flag_show_ends: .asciz "--show-ends" flag_E: .asciz "-E" flag_number: .asciz "--number" flag_n: .asciz "-n" +flag_number_nonblank: .asciz "--number-nonblank" +flag_b: .asciz "-b" .section .text -.globl _start, show_ends, number +.globl _start, show_ends, number, number_nonblank # main. _start: @@ -162,6 +166,12 @@ _check_flags: bnez a0, .LMainReturnErr sb a1, number, t1 + la a0, flag_number_nonblank + la a1, flag_b + call has_switch + bnez a0, .LMainReturnErr + sb a1, number_nonblank, t1 + ld ra, 0(sp) addi sp, sp, 8 ret @@ -207,6 +217,16 @@ _is_known_flag: call str_cmp bnez a1, .LFlagFound + la a0, flag_number_nonblank + mv a1, s0 + call str_cmp + bnez a1, .LFlagFound + + la a0, flag_b + mv a1, s0 + call str_cmp + bnez a1, .LFlagFound + li a1, 0 .LFlagFound: ld s0, 0(sp) diff --git a/src/mod.S b/src/mod.S index 12aa967..7bc3980 100644 --- a/src/mod.S +++ b/src/mod.S @@ -68,11 +68,11 @@ add_endings: # @param[in] a0: ptr to null-terminated str. # @param[in] a1: length of str. # @param[in] a2: mod buf addr. -# @param[in] a3: skip empty. # @param[out] a0: result code. # @param[out] a1: bytes written to mod buf. add_line_numbers: - addi sp, sp, -64 + addi sp, sp, -72 + sd s7, 64(sp) # skip empty sd s6, 56(sp) # mod buf ptr sd s5, 48(sp) # mod buf bp sd s4, 40(sp) # str buf ptr @@ -82,6 +82,8 @@ add_line_numbers: sd s1, 8(sp) # len of str sd s0, 0(sp) # str buf addr + la t0, number_nonblank + lb s7, 0(t0) mv s0, a0 # put the str ptr in s0 mv s1, a1 # move length of str into s1 @@ -111,11 +113,20 @@ add_line_numbers: add s4, s0, s2 # Calculate the offset address lb t6, 0(s4) li t4, 0xA # newline - bne t6, t4, 1f # if the current byte is not a newline, skip to writing + bne t6, t4, 1f # if the current byte IS NOT a newline, skip to writing mv t0, s2 addi t0, t0, 1 # move ahead one char and see if EOF - bge t0, s1, 1f # if the newline is at the veyr end, we don't indicate a new line number + bge t0, s1, 1f # if the newline is at the very end, we don't indicate a new line number + beqz s7, .LLineNumbersSkipEmptyCheck + mv t0, s4 # move the current string buf pointer into t0 + li t1, 1 + sub t0, t0, t1 # move the str pointer back one + lb t0, 0(t0) + # t4 still contains a newline char + beq t0, t4, 1f # if the previous byte IS a newline, skip to writing + + .LLineNumbersSkipEmptyCheck: call _inc_line_count @@ -165,7 +176,8 @@ add_line_numbers: ld s4, 40(sp) ld s5, 48(sp) ld s6, 56(sp) - addi sp, sp, 64 + ld s6, 64(sp) + addi sp, sp, 72 ret -- 2.54.0 From ca7daa1734124fa52325815328378b4e73465527 Mon Sep 17 00:00:00 2001 From: lexzach Date: Tue, 15 Sep 2026 16:08:52 -0400 Subject: [PATCH 2/3] Finish number-nonblank --- src/cat.S | 20 ++++++++++++++++++++ src/mod.S | 5 ++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/cat.S b/src/cat.S index 1de6eb3..78d3e0e 100644 --- a/src/cat.S +++ b/src/cat.S @@ -42,6 +42,26 @@ cat_file: mv s2, a0 li s1, 1 + la t1, number_nonblank + lb t1, 0(t1) + beqz t1, .LNoNonblankNumbers + + mv a1, s2 # load mod buf size to a1 + + beqz s1, 1f + la a0, mod_buf_0 # load mod_buf_0 as read buf + la a2, mod_buf_1 # load mod_buf_1 as write buf + j 2f + 1: + la a0, mod_buf_1 # load mod_buf_1 as read buf + la a2, mod_buf_0 # load mod_buf_0 as write buf + 2: + + call add_line_numbers + xori s1, s1, 1 # flip the mod buf to write to + mv s2, a1 # update the current byte count + .LNoNonblankNumbers: + la t1, number lb t1, 0(t1) beqz t1, .LNoNumbers diff --git a/src/mod.S b/src/mod.S index 7bc3980..1441ebb 100644 --- a/src/mod.S +++ b/src/mod.S @@ -120,11 +120,10 @@ add_line_numbers: beqz s7, .LLineNumbersSkipEmptyCheck mv t0, s4 # move the current string buf pointer into t0 - li t1, 1 - sub t0, t0, t1 # move the str pointer back one + addi t0, t0, 1 # move the str pointer forward one lb t0, 0(t0) # t4 still contains a newline char - beq t0, t4, 1f # if the previous byte IS a newline, skip to writing + beq t0, t4, 1f # if the next byte IS a newline, skip to writing .LLineNumbersSkipEmptyCheck: -- 2.54.0 From 1d5eed6f2296b338f9fc743f35497e57f9f2b2bd Mon Sep 17 00:00:00 2001 From: lexzach Date: Tue, 15 Sep 2026 16:10:54 -0400 Subject: [PATCH 3/3] Make -b and -n exclusive --- src/cat.S | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cat.S b/src/cat.S index 78d3e0e..be77763 100644 --- a/src/cat.S +++ b/src/cat.S @@ -60,6 +60,7 @@ cat_file: call add_line_numbers xori s1, s1, 1 # flip the mod buf to write to mv s2, a1 # update the current byte count + j .LNoNumbers # -n and -b are exclusive .LNoNonblankNumbers: la t1, number -- 2.54.0