Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement unexpand #159

Merged
merged 5 commits into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ Contributions are welcome!
Please only contribute versions of the original utilities written in V.
Contributions written in other languages will likely be rejected.

When your contribution is finalized, don't forget to update the completed
When your contribution is finalized, don't forget to update the completed
count below and mark it as done in this README.md. Thanks!

**NOTE: When testing on Windows**, comparison tests are currently run against
[uutils/coreutils](https://github.com/uutils/coreutils), a Rust re-implementation of
GNU coreutils. They are not 100% compatiable. If you encounter different behaviors,
**NOTE: When testing on Windows**, comparison tests are currently run against
[uutils/coreutils](https://github.com/uutils/coreutils), a Rust re-implementation of
GNU coreutils. They are not 100% compatiable. If you encounter different behaviors,
compare against the true GNU coreutils version on the Linux-based tests first.

## Completed (60/109)
## Completed (62/109)

| Done | Cmd | Descripton |
| :-----: | --------- | ------------------------------------------------ |
Expand Down Expand Up @@ -95,7 +95,7 @@ compare against the true GNU coreutils version on the Linux-based tests first.
| | link | Make a hard link via the link syscall |
| ✓ | ln | Make links between files |
| ✓ | logname | Print current login name |
| | ls | List directory contents |
| ✓ | ls | List directory contents |
| ✓ | md5sum | Print or check MD5 digests |
| ✓ | mkdir | Make directories |
| | mkfifo | Make FIFOs (named pipes) |
Expand Down Expand Up @@ -149,7 +149,7 @@ compare against the true GNU coreutils version on the Linux-based tests first.
| | tsort | Topological sort |
| ✓ | tty | Print file name of terminal on standard input |
| ✓ | uname | Print system information |
| | unexpand | Convert spaces to tabs |
| ✓ | unexpand | Convert spaces to tabs |
| ✓ | uniq | Uniquify files |
| ✓ | unlink | Remove files via the unlink syscall |
| ✓ | uptime | Print system uptime and load |
Expand Down
79 changes: 79 additions & 0 deletions src/unexpand/args.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import common
import flag
import os
import time

const app_name = 'unexpand'
const spaces = flag.space

struct Options {
all bool
first_only bool
tabs string
files []string
}

fn get_options() Options {
mut fp := common.flag_parser(os.args)
fp.application(app_name)
fp.description('Convert spaces to tabs')
fp.arguments_description('[files]')

all := fp.bool('all', `a`, false, 'convert all blanks instead of just initial blanks')
first_only := fp.bool('first-only', ` `, false, 'convert only leading sequences of blanks (overrides -a)')
tabs := fp.string('list', `t`, '', 'use comma separated list of tab positions.\n${spaces}' +
"The last specified position can be prefixed with '/'\n${spaces}" +
'to specify a tab size to use after the last$\n${spaces}' +
"explicitly specified tab stop. Also a prefix of '+'\n${spaces}" +
'can be used to align remaining tab stops relative to$\n${spaces}' +
'the last specified tab stop instead of the first column\n')
files := fp.finalize() or { exit_error(err.msg()) }

return Options{
all: all
first_only: first_only
tabs: tabs
files: scan_files_arg(files)
}
}

fn scan_files_arg(files_arg []string) []string {
mut files := []string{}

for file in files_arg {
if file == '-' {
files << stdin_to_tmp()
continue
}
files << file
}

if files.len == 0 {
files << stdin_to_tmp()
}

return files
}

const tmp_pattern = '/${app_name}-tmp-'

fn stdin_to_tmp() string {
tmp := '${os.temp_dir()}/${tmp_pattern}${time.ticks()}'
os.create(tmp) or { exit_error(err.msg()) }
mut f := os.open_append(tmp) or { exit_error(err.msg()) }
defer { f.close() }

for {
s := os.get_raw_line()
if s.len == 0 {
break
}
f.write_string(s) or { exit_error(err.msg()) }
}
return tmp
}

@[noreturn]
fn exit_error(msg string) {
common.exit_with_error_message(app_name, msg)
}
Empty file removed src/unexpand/delete.me
Empty file.
Loading
Loading