~sircmpwn/ctools

c4f53be2706addcd9678af7d614d69edc6f9769e — Pedro L. Ramos 1 year, 7 days ago 5877054
Implement echo

The behaviour of echo command is to print exactly as the arguments are,
unless -n is in which the escape chars are recognized.
7 files changed, 182 insertions(+), 3 deletions(-)

M STATUS
A doc/echo.1.scd
M doc/meson.build
M meson.build
A src/echo.c
A test/echo
M test/meson.build
M STATUS => STATUS +1 -1
@@ 41,7 41,7 @@ T       df
T       diff
  D     dirname
T       du
T       echo
  D     echo
T       ed*
  D     env
    W   ex

A doc/echo.1.scd => doc/echo.1.scd +61 -0
@@ 0,0 1,61 @@
echo(1) "ctools"

# NAME

echo - writes arguments to the standard output 

# SYNOPSIS

*echo* [-n] [_string_...]

# DESCRIPTION

*echo* writes each of its arguments to standard out, joined with a
space, then writes a newline. If no arguments are given, a newline
is still printed.


# OPTIONS

*-n*
	Supress the output of a final newline after the last argument

# OPERANDS

	_string_
		string to be written to standard output. If -n is used as argument 
		the following escape characters will be recognized:

		\\a
			<alert>
		
		\\b
			<backspace>
		
		\\c
			Suppress the final <newline> and all characters following
		
		\\f
			<form-feed>

		\\n
			<newline>

		\\r
			<carrieage-return>
		
		\\t
			<tab>
		
		\\v 
			<vertical-tab>
		
		\\\\
			<backslash>

# DISCLAIMER

This command is part of ctools and is compatible with POSIX-1.2017, and may
optionally support XSI extensions. This man page is not intended to be a
complete reference, and where it disagrees with the specification, the
specification takes precedence.

M doc/meson.build => doc/meson.build +1 -0
@@ 13,6 13,7 @@ man_files = [
	'cmp.1',
	'comm.1',
	'dirname.1',
	'echo.1',
	'env.1',
	'false.1',
	'head.1',

M meson.build => meson.build +1 -0
@@ 20,6 20,7 @@ oneshots = [
	'cmp',
	'comm',
	'dirname',
	'echo',
	'env',
	'false',
	'head',

A src/echo.c => src/echo.c +87 -0
@@ 0,0 1,87 @@
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static void
usage(void)
{
	fprintf(stderr, "usage: echo [-n] [string...]");
}

int
main(int argc, char *argv[])
{
	int nflag = 0;
	char opt;

	while ((opt = getopt(argc, argv, "n")) != -1) {
		switch (opt) {
		case 'n':
			nflag = 1;
			break;
		default:
			usage();
			return 1;
		}
	}

	for (int i = optind; i < argc; ++i) {
		char *arg = NULL;
		for (arg = argv[i]; *arg; arg++) {
			if (arg[0] == '\\' && nflag) {
				switch (arg[1]) {
				case 'a':
					putchar('\a');
					arg++;
					break;
				case 'b':
					putchar('\b');
					arg++;
					break;
				case 'c':
					putchar('\n');
					arg++;
					return 0;
				case 'f':
					putchar('\f');
					arg++;
					break;
				case 'n':
					putchar('\n');
					arg++;
					break;
				case 'r':
					putchar('\r');
					arg++;
					break;
				case 't':
					putchar('\t');
					arg++;
					break;
				case 'v':
					putchar('\v');
					arg++;
					break;
				case '\\':
					putchar('\\');
					arg++;
					break;
				default:
					putchar(arg[0]);
					break;
				}
			} else {
				putchar(arg[0]);
			}
		}
		if (i != argc - 1) {
			putchar(' ');
		}
	}

	if (!nflag) {
		putchar('\n');
	}
}

A test/echo => test/echo +29 -0
@@ 0,0 1,29 @@
#!/bin/sh
tool="echo"
. "$HARNESS"

should_handle_one_string() (
	ct="$(../build/echo "this is a test string")"
	[ "$ct" = "this is a test string" ]
)

should_handle_two_string() (
	ct="$(../build/echo "this is a test string" "this second string")"
	[ "$ct" = "this is a test string this second string" ]
)

should_handle_tab_char() (
	ct="$(../build/echo -n "\tthis is a test string")"
	[ "$ct" = '	this is a test string' ]
)

should_handle_c_escape_char() (
	ct="$(../build/echo -n "this is a \ctest string")"
	[ "$ct" = "this is a " ]
)

runtests \
	should_handle_one_string \
	should_handle_two_string \
	should_handle_tab_char \
	should_handle_c_escape_char

M test/meson.build => test/meson.build +2 -2
@@ 1,15 1,15 @@
harness=join_paths(meson.current_source_dir(), 'harness.sh')

test_files = [
	'basename',
	'cat',
	'chgrp',
	'chown',
	'chmod',
	'chown',
	'cksum',
	'cmp',
	'comm',
	'dirname',
	'echo',
	'env',
	'false',
	'head',