Skip to content

Add printf, read, break, continue, command, and type builtins#280

Merged
wolfv merged 6 commits intomainfrom
claude/bash-solid-refactor-uH7Vz
Mar 17, 2026
Merged

Add printf, read, break, continue, command, and type builtins#280
wolfv merged 6 commits intomainfrom
claude/bash-solid-refactor-uH7Vz

Conversation

@wolfv
Copy link
Member

@wolfv wolfv commented Mar 17, 2026

This PR adds several important shell builtins and improves file test operator support in the deno_task_shell.

Summary

Implements missing shell builtins (printf, read, break, continue, command, type) and expands file test operator coverage to support more POSIX-compliant conditional expressions.

Key Changes

New Builtins

  • printf: Full printf implementation with format specifiers (%s, %d, %i, %o, %x, %X, %f, %c, %b), escape sequences (\n, \t, \r, \, \a, \b, \f, \v, \0NNN), and width/precision modifiers
  • read: Reads input from stdin into shell variables with support for -r (raw mode) and -p (prompt) flags; defaults to REPLY variable
  • break/continue: Loop control flow commands that work in for and while loops
  • command: Implements command -v to locate commands, bypassing aliases
  • type: Describes how command names would be interpreted (aliases, builtins, or external commands)
  • colon (:): No-op command that always returns 0

File Test Operators

Expanded conditional expression support with proper implementations:

  • -b, -c: Block/character special files (Unix-only)
  • -p: Named pipes (Unix-only)
  • -s: File size greater than zero
  • -u, -g: Setuid/setgid bits
  • -k: Sticky bit
  • -O, -G: File ownership checks (Unix-only)
  • -N: File modified since last read (Unix-only)
  • -t: Terminal file descriptor checks
  • Proper path resolution relative to shell's CWD for all file tests

Loop Control Flow

  • Added BREAK_EXIT_CODE and CONTINUE_EXIT_CODE sentinel values for signaling loop control
  • Updated execute_for_clause and execute_while_clause to handle break/continue properly

Other Improvements

  • Better error handling in parser with proper error messages instead of unwrap()
  • Added Unix-specific dependency (libc) for file permission checks
  • Improved error handling in various command implementations
  • Fixed unreachable code patterns with proper error returns

Implementation Details

  • File test operators resolve relative paths against the shell's current working directory
  • The printf command supports both POSIX format specifiers and bash extensions like %b
  • The read command handles backslash escapes and properly splits input across multiple variables
  • Loop control flow uses special exit codes that are intercepted and converted back to normal exit code 0

https://claude.ai/code/session_01GTXgqqxHbE7ACysQDZ9cLU

claude and others added 6 commits March 16, 2026 21:32
…x path resolution

- Replace panic!() in parser (for loop wordlist) and types (arithmetic) with
  proper error handling/fallback behavior
- Replace unreachable!() in parser (and_or lists, boolean operators), execute
  (assignment operators), and main (script/command dispatch) with descriptive errors
- Implement all 14 previously unimplemented file test operators: -b (block special),
  -c (char special), -g (setgid), -k (sticky bit), -p (named pipe), -s (size > 0),
  -t (terminal fd), -u (setuid), -G (owned by egid), -N (modified since read),
  -O (owned by euid), -S (socket), -R (nameref), and None (implicit -n)
- Add -e (file exists) and -t (terminal fd) to grammar and parser
- Fix file test path resolution to use shell CWD instead of process CWD
- Fix critical unwrap() calls in main.rs (current_dir), execute.rs (parse result),
  uname.rs, touch.rs (DST-ambiguous datetimes), set.rs, and mod.rs (clear command)
- Add comprehensive test suite for file test operators (3 new test functions)

https://claude.ai/code/session_01GTXgqqxHbE7ACysQDZ9cLU
… type

Implement 7 new shell builtins for improved bash compatibility:
- break/continue: Loop control flow via sentinel exit codes (-100/-101)
  that propagate through ExecuteResult::Exit and are caught by while/for loops
- : (colon): No-op command that always returns 0
- printf: Format string support with %s, %d, %o, %x, %f, %c, %b specifiers,
  width/precision/flags, and standard escape sequences
- read: Read input with -r (raw) and -p (prompt) flags, field splitting,
  default REPLY variable
- command: Run commands bypassing aliases, -v flag for path lookup
- type: Describe how a command name resolves (alias, builtin, or PATH)

All builtins include comprehensive tests.

https://claude.ai/code/session_01GTXgqqxHbE7ACysQDZ9cLU
Implement 6 more shell builtins for improved bash compatibility:
- eval: Parse and execute string arguments as shell commands
- source/.: Fix to use context pipes instead of real stdout/stderr,
  enabling proper pipe capture in tests and subshells. Read file,
  parse, and execute in current shell context with env change propagation
- shift: Shift positional parameters ($1, $2, ...) left by N
- local: Declare shell-scoped variables (foundation for future
  function support)
- return: Exit from sourced scripts with specified exit code via
  ExecuteResult::Exit propagation
- trap: Basic signal handling with -l (list signals), -p (print traps),
  and handler registration acceptance for compatibility

All builtins include comprehensive tests. Total: 46 tests passing.

https://claude.ai/code/session_01GTXgqqxHbE7ACysQDZ9cLU
…e groups

- Add function_definition parsing (foo() { ... }) with FunctionDefinition AST node
- Store functions in ShellState and execute via execute_shell_function
- Support positional parameters ($1-$N, $#, $@, $*) with save/restore across calls
- Fix grammar: UNQUOTED_ESCAPE_CHAR now excludes SPECIAL_PARAM so $1/$2/etc parse correctly
- Fix RETURN_EXIT_CODE sentinel handling at top level and in function scope
- Sync last_command_exit_code with shell var "?" for proper $? expansion
- Add brace group compound command support
- Add comprehensive tests for functions, positional params, return values, nested calls

https://claude.ai/code/session_01GTXgqqxHbE7ACysQDZ9cLU
- functions.sh: tests for function definitions, positional parameters
  ($1-$N, $#, $@), nested calls, variable scoping, and function overriding
- builtins.sh: tests for eval, shift, local, and brace groups

https://claude.ai/code/session_01GTXgqqxHbE7ACysQDZ9cLU
@wolfv wolfv merged commit 060623b into main Mar 17, 2026
8 checks passed
@wolfv wolfv deleted the claude/bash-solid-refactor-uH7Vz branch March 17, 2026 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants