~nabijaczleweli/voreutils

8252842e7ff74305e5642881658959dc00307d44 — наб a month ago 8f22342
Add echo
M README.md => README.md +1 -1
@@ 13,7 13,7 @@ GNU coreutils provide the following 105 binaries, according to `dpkg -L coreutil
  [ ] /bin/dd
  [ ] /bin/df
  [ ] /bin/dir
  [ ] /bin/echo
  [x] /bin/echo – `-n` only
  [x] /bin/false
  [ ] /bin/ln
  [ ] /bin/ls

A cmd/echo.cpp => cmd/echo.cpp +41 -0
@@ 0,0 1,41 @@
// SPDX-License-Identifier: 0BSD


#include <cstdio>
#include <cstring>
#include <errno.h>
#include <string_view>
#include <vore-optarg>

using namespace std::literals;


int main(int, const char * const * argv) {
	const char * argv0 = argv[0];
	if(*argv)
		++argv;

	bool newline = true;
	if(*argv && *argv == "-n"sv) {
		++argv;
		newline = false;
	}

	bool first = true;
	for(const char * arg : vore::opt::args{argv}) {
		if(first)
			first = false;
		else
			std::fputc(' ', stdout);

		std::fputs(arg, stdout);
	}

	if(newline)
		std::fputc('\n', stdout);

	if(std::fflush(stdout)) {
		std::fprintf(stderr, "%s: %s\n", argv0, std::strerror(errno));
		return 1;
	}
}

M include/vore-optarg => include/vore-optarg +0 -2
@@ 3,8 3,6 @@

#pragma once

#include <iterator>


namespace vore {
	template <class T>

A man/echo.1 => man/echo.1 +32 -0
@@ 0,0 1,32 @@
.\" SPDX-License-Identifier: 0BSD
.\"
.Dd
.Dt ECHO 1
.Os
.
.Sh NAME
.Nm echo
.Nd print arguments
.Sh SYNOPSIS
.Nm
.Op Fl n
.Oo Ar string Oc Ns …
.
.Sh DESCRIPTION
Writes each
.Ar string ,
separated by a single space
.Pq Qq " " ,
to the standard output.
.Pp
If
.Fl n
is specified as the first argument, it's skipped.
Otherwise, the newline character is written after all
.Ar string Ns s .
.
.Sh EXIT STATUS
.Sy 0
if no errors (like the output exceeding its quota) were encountered while writing, otherwise
.Sy 1
and a diagnostic is issued.

A tests/echo/data/-n => tests/echo/data/-n +0 -0
A tests/echo/data/-n-n => tests/echo/data/-n-n +1 -0
@@ 0,0 1,1 @@
-n
\ No newline at end of file

A tests/echo/data/-n__ => tests/echo/data/-n__ +1 -0
@@ 0,0 1,1 @@
 
\ No newline at end of file

A tests/echo/data/-na_b_c => tests/echo/data/-na_b_c +1 -0
@@ 0,0 1,1 @@
a b c
\ No newline at end of file

A tests/echo/data/_ => tests/echo/data/_ +1 -0
@@ 0,0 1,1 @@


A tests/echo/data/__ => tests/echo/data/__ +1 -0
@@ 0,0 1,1 @@
 

A tests/echo/data/a_b_c => tests/echo/data/a_b_c +1 -0
@@ 0,0 1,1 @@
a b c

A tests/echo/data/blank => tests/echo/data/blank +1 -0
@@ 0,0 1,1 @@


A tests/echo/test => tests/echo/test +30 -0
@@ 0,0 1,30 @@
#!/bin/sh
# SPDX-License-Identifier: 0BSD

# GNU coreutils ship their own regexes(!), which recognise \s but don't [[:space:]]
# Conversely, regcomp(3) universally recognises [[:space:]], but not always \s (glibc does, Berkeley libcs don't)
# For ease of testing (and regeneration), pat= is set to [[:space:]] if it's \s: if retesting against GNU tac or regenerating, comment out those lines

IFS="
"

echo="${CMDDIR}echo"

"$echo" -n -n    | cmp data/-n-n    || echo "echo: -n -n     wrong" >&3
"$echo" -n a b c | cmp data/-na_b_c || echo "echo: -n a b c  wrong" >&3
"$echo" -n       | cmp data/-n      || echo "echo: -n        wrong" >&3
"$echo" -n '' '' | cmp data/-n__    || echo "echo: -n '' ''  wrong" >&3
"$echo" a b c    | cmp data/a_b_c   || echo "echo: a b c     wrong" >&3
"$echo" '' ''    | cmp data/__      || echo "echo: '' ''     wrong" >&3
"$echo"          | cmp data/blank   || echo "echo:           wrong" >&3
"$echo" ''       | cmp data/_       || echo "echo: ''        wrong" >&3

[ -w '/dev/full' ] || {
  echo "echo: skipping error testing, /dev/full unavailable" >&2
  exit 0
}

msg="$("$echo" 2>&1 > /dev/full)" && echo "echo: /dev/full okay?" >&3
[ -n "$msg" ]                     || echo "echo: no message after /dev/full?" >&3

"$echo" -n 2>&3 > /dev/full || echo "echo: /dev/full with no output wrong?" >&3