From 90b6c515ca0fe027ca68504d26e6892fabdfe6cd Mon Sep 17 00:00:00 2001 From: lexzach Date: Tue, 15 Sep 2026 12:10:33 -0400 Subject: [PATCH] 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