linux-sysprog · intermediate · ~45 min
Stateful character-by-character parsing with multiple modes (in-word / in-quote).
Tokenise a command line into an argv vector the way a shell does, honouring double-quoted strings.
Implement int shell_split(const char *line, char **argv, int max_argv) that splits line into tokens and stores a freshly allocated copy of each token in argv.
line: a NUL-terminated command line. Tokens are separated by spaces/tabs; a run inside "..." is one token (the quotes are stripped, and whitespace inside them is kept).argv, max_argv: the output array and its capacity (pointer slots).Stores up to max_argv - 1 token pointers in argv[0..ret-1] — each made with strdup, so the caller frees them — then sets argv[ret] = NULL. Does not modify line. Returns the token count, or -1 if a quote is never closed.
shell_split("ls -la /tmp", argv, 16) -> 3 argv = {"ls","-la","/tmp"}
shell_split("echo \"hello world\"", argv, 16) -> 2 argv = {"echo","hello world"}
shell_split("", argv, 16) -> 0
shell_split("oops \"never ends", argv, 16) -> -1 (unterminated quote)
" returns -1 (and frees any tokens already allocated).line; copy each token with strdup (don't use strtok).argv after the last token.A POSIX shell is at heart a tokenizer + a fork/exec loop. The trickiest bit is splitting a command line into argv while respecting quotes — every shell on every UNIX-like OS does this dance, and getting it right is a great pointer/string exercise.
A NUL-terminated command line, an output array argv, and its capacity max_argv. Tokens split on whitespace; "..." groups one token without the quotes.
strdup'd token pointers in argv[0..ret-1], then argv[ret]=NULL. Returns the token count, or -1 on an unterminated quote.
Do not modify line (don't use strtok). Write at most max_argv-1 tokens. Always NULL-terminate argv.
#include <stddef.h>
int shell_split(const char *line, char **argv, int max_argv) { /* TODO */ return 0; }
Mishandling escape sequences (we don't require them — keep it simple); forgetting to NULL-terminate argv; not freeing tokens on the error path.
Empty line returns 0. Trailing whitespace. Two consecutive spaces. Quoted empty string "".
O(n) time, O(tokens) memory.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.