Skip to content

Commit

Permalink
fix: whitespace output
Browse files Browse the repository at this point in the history
  • Loading branch information
igrekus committed Jun 3, 2024
1 parent 508b79b commit db1579a
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 35 deletions.
25 changes: 19 additions & 6 deletions src/sum/parse_args.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,32 @@ import common
import os
import time

const app_name = 'sum'
const app_description = '
Print checksum and block counts for each FILE.
With no FILE, or when FILE is -, read standard input.'

struct Args {
sys_v bool
files []string
}

fn parse_args(args []string) Args {
mut fp := common.flag_parser(args)
fp.application(app_name)
fp.description('
Print or check BSD (16-bit) checksums.
fp.description(app_description)

With no FILE, or when FILE is -, read standard input.'.trim_indent())

fp.bool('', `r`, true, 'use BSD sum algorithm (the default), use 1K blocks')
sys_v := fp.bool('sysv', `s`, false, 'use System V sum algorithm, use 512 bytes blocks')
fp.bool('', `r`, true, 'use BSD sum algorithm, use 1K blocks')
mut sys_v := fp.bool('sysv', `s`, false, 'use System V sum algorithm, use 512 bytes blocks')
files_arg := fp.finalize() or { exit_error(err.msg()) }
files := scan_files_arg(files_arg)

// emulate original algorithm switches behavior
if '-rs' in args {
sys_v = true
}

return Args{
sys_v: sys_v
files: files
Expand Down
88 changes: 75 additions & 13 deletions src/sum/sum.v
Original file line number Diff line number Diff line change
@@ -1,33 +1,96 @@
import os

const app_name = 'sum'

struct Args {
sys_v bool
files []string
struct Sum {
checksum u16
block_count u64
mut:
file_name string
}

const bsd_block_size = 1024
const sysv_block_size = 512


fn main() {
args := parse_args(os.args)
mut sums := []Sum{}
mut block_size := match args.sys_v {
true { sysv_block_size }
false { bsd_block_size }
}

for file in args.files {
println(sum(file, args.sys_v))
checksum, mut blocks, file_name := sum(file, args.sys_v)
blocks = get_file_block_count(file, block_size)
sums << Sum{checksum, blocks, file_name}
}

if args.sys_v {
print_sysv(sums)
} else {
print_bsd(mut sums)
}
}

fn get_file_block_count(file string, block_size int) u64 {
file_size := os.file_size(file)
mut blocks := file_size / u64(block_size)
if file_size % u64(block_size) != 0 {
blocks += 1
}
return blocks
}

fn get_stream_block_count(read_byte_count int, block_size int, current_count u64) u64 {
if read_byte_count % block_size != 0 {
return current_count + u64(read_byte_count / block_size) + 1
} else {
return current_count + u64(read_byte_count / block_size)
}
}


fn print_sysv(sums []Sum) {
for sum in sums {
println('${sum.checksum} ${sum.block_count}${sum.file_name}'.trim_space())
}
}

fn print_bsd(mut sums []Sum) {
if sums.len == 1 {
sums[0].file_name = ''
}
for sum in sums {
mut block_str := sum.block_count.str()
if block_str.len <= 5 {
block_str = rjust(block_str, 5)
}
checksum_str := '${sum.checksum:05}'
println('${checksum_str} ${block_str}${sum.file_name}'.trim_space())
}
}

fn rjust(s string, width int) string {
if width == 0 {
return s
}
return ' '.repeat(width - s.len) + s
}

fn sum(file string, sys_v bool) string {
fn sum(file string, sys_v bool) (u16, u64, string) {
digest, blocks := match sys_v {
true { sum_sys_v(file) }
else { sum_bsd(file) }
}

name := if file.contains('/sum-') { '' } else { file }
return '${digest:5} ${blocks:5} ${name}'
name := if file.contains('/sum-') { '' } else { ' ${file}' }
return digest, blocks, name
}

fn sum_bsd(file string) (u16, int) {
fn sum_bsd(file string) (u16, u64) {
mut count := 0
mut checksum := u16(0)
mut blocks := u64(0)
mut f := os.open(file) or { exit_error(err.msg()) }
defer { f.close() }

Expand All @@ -39,13 +102,13 @@ fn sum_bsd(file string) (u16, int) {
count += 1
}

blocks := count / 1024 + 1
return checksum, blocks
}

fn sum_sys_v(file string) (u16, int) {
fn sum_sys_v(file string) (u16, u64) {
mut sum := u32(0)
mut count := u32(0)
mut blocks := u64(0)
mut f := os.open(file) or { exit_error(err.msg()) }
defer { f.close() }

Expand All @@ -57,6 +120,5 @@ fn sum_sys_v(file string) (u16, int) {

r := (sum & 0xffff) + ((sum & 0xffffffff) >> 16)
checksum := u16((r & 0xffff) + (r >> 16))
blocks := count / 512 + 1
return checksum, blocks
}
38 changes: 22 additions & 16 deletions src/sum/sum_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const test2_txt = os.join_path(testing.temp_folder, 'test2.txt')
const test3_txt = os.join_path(testing.temp_folder, 'test3.txt')
const long_line = os.join_path(testing.temp_folder, 'long_line')
const large_file = os.join_path(testing.temp_folder, 'large_file')
const main_txt = os.join_path(testing.temp_folder, 'test.txt')

fn test_help_and_version() {
cmd.ensure_help_and_version_options_work()!
Expand All @@ -32,6 +33,9 @@ fn testsuite_begin() {
os.write_file(test3_txt, 'dummy')!
os.write_file(long_line, 'z'.repeat(1024 * 151))!
os.write_file(large_file, 'z'.repeat(110 * 1024 * 1024))!

sample_file_name := @FILE.trim_right('sum_test.v') + 'test.txt'
os.cp(sample_file_name, main_txt)!
}

fn testsuite_end() {
Expand All @@ -40,6 +44,24 @@ fn testsuite_end() {
os.rm(test3_txt)!
os.rm(long_line)!
os.rm(large_file)!
os.rm(main_txt)!
}

/*
tests from main branch for completeness
*/
fn test_bsd() {
res := os.execute('cat ${main_txt} | ${executable_under_test} -r')

assert res.exit_code == 0
assert res.output == '38039 1${eol}'
}

fn test_sysv() {
res := os.execute('cat ${main_txt} | ${executable_under_test} -s')

assert res.exit_code == 0
assert res.output == '25426 1${eol}'
}

/*
Expand Down Expand Up @@ -167,19 +189,3 @@ fn test_bsd_block_col_width_more_than_5_not_aligned() {
assert res.exit_code == 0
assert res.output == '59852 1 ${test1_txt}${eol}62707 112640 ${large_file}${eol}11628 1 ${test2_txt}${eol}'
}

module main

import os

fn testsuite_begin() {
os.chdir(os.dir(@FILE))!
}

fn test_bsd() {
assert sum('test.txt', false) == '38039 1 test.txt'
}

fn test_sysv() {
assert sum('test.txt', true) == '25426 1 test.txt'
}

0 comments on commit db1579a

Please sign in to comment.