coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

coreutils/src/echo.c (43 lines, 1.3 KiB) -rw-r--r-- blame download

0123456789101112131415161718192021222324252627282930313233343536373839404142
// echo.c, version 1.1.0
// OMKOV coreutils implementation of POSIX echo
// Copyright (C) 2020, Jakob Wakeling
// MIT Licence

#include <stdio.h>
#include <stdlib.h>

static inline void echo(const char *s);

int main(int ac, char *av[]) { (void)ac;
	register char **p = &av[1]; if (*p) { echo(*p);
		for (++p; *p; ++p) { fputc(' ', stdout); echo(*p); }
	} fputc('\n', stdout); return 0;
}

/*
	Echo a string to stdout character by character.
	Escape sequences are processed according to XSI.
*/
static inline void echo(const char *s) {
	for (const char *p = s; *p; ++p) {
		if (*p == '\\' && p[1]) switch (*++p) {
		case 'a': { fputc('\a', stdout); continue; }
		case 'b': { fputc('\b', stdout); continue; }
		case 'c': { exit(0); }
		case 'f': { fputc('\f', stdout); continue; }
		case 'n': { fputc('\n', stdout); continue; }
		case 'r': { fputc('\r', stdout); continue; }
		case 't': { fputc('\t', stdout); continue; }
		case 'v': { fputc('\v', stdout); continue; }
		case '\\': { fputc('\\', stdout); continue; }
		case '0': {
			register int n = 0, d = 0;
			for (++p; (*p >= '0' && *p <= '7') && d++ != 3; ++p) {
				n <<= 3; n |= (*p - '0');
			} fputc(n, stdout); --p; continue;
		}
		default: { fputc('\\', stdout); fputc(*p, stdout); }
		} else { fputc(*p, stdout); continue; }
	} return;
}