Decoded: expand (coreutils)

[Back to Project Main Page]

Note: This page explores the design of command-line utilities. It is not a user guide.
[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]

Logical flow of expand command (coreutils)

Summary

expand - convert tabs to spaces

[Source] [Code Walkthrough]

Lines of code: 239
Principal syscalls: write() (via putchar())
Support syscall: None
Options: 2 (36 short, 4 long)

Descended from expand introduced in 3BSD (1979)
Added to Textutils in November 1992 [First version]
Number of revisions: 132 [Code Evolution]

The expand utility has a sister utility, unexpand. Many of the common functions shared between both have been factored out and live in an included file, expand-common.c. Many of the design concepts are shared between both utilities.

Helpers:
  • expand() - The worker function that changes all tabs to spaces and prints
External non-standard helpers:
  • cleanup_file_list_stdin() - Closes STDIN file list
  • die() - Exit with mandatory non-zero error and message to stderr
  • finalize_tab_stops() - Sets the final tab stop values
  • get_next_tab_column() - Returns the position of the next tab stop
  • parse_tab_stops() - Adds more tab stops to the existing list
  • set_file_list() - Assigns the file list

Setup

The expand utility has a deceptively simple setup. All of the globals are included in expand-common.c. One global used directly in expand.c is:

  • convert_entire_line - Flag to indicate processing entire line (default off, leading tabs only)

Only one variable is declared in main(), c, which holds the next option for processing


Parsing

Parsing for expand answers these questions:

  • Do we change only leading tabs, or the entire line?
  • Where are the tabs and how large are they (default 8 spaces)

A legacy syntax is also supported, where the tab stops appear as integer option values

Parsing failures

The only parsing failure occurs if the user provides an unknown option


Execution

The expand procedures look like this:

  • Using the parsed information, set the final tab stop positions
  • Prepare the input file list
  • Process all files, all lines
    • Handle each tab and backspace (partial or full line as requested)
    • Output normal characters as usual

Failure cases:

  • Unable to output character
  • The input line is too long

[Back to Project Main Page]