Skip to content

Instantly share code, notes, and snippets.

@clausecker
Created October 26, 2014 16:05
Show Gist options
  • Select an option

  • Save clausecker/a374850ed3c869731c14 to your computer and use it in GitHub Desktop.

Select an option

Save clausecker/a374850ed3c869731c14 to your computer and use it in GitHub Desktop.
My implementation of echo(1)
/*-
* Copyright (c) 2014 Robert Clausecker <[email protected]>
*/
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include "err.h"
extern int main(int, char*[]);
static const char *escape(const char*);
static void put(int);
/*
* Implementation of echo(1) according to IEEE Std 1003.1, 2013 edition.
* This implementation implements the behavior for -n an \ as specified for
* XSI-conformant systems and outputs unrecognized escape sequences unchanged.
*/
extern int
main(int argc, char *argv[])
{
int i;
const char *arg;
setprogname(argv[0]);
for (i = 1; i < argc; i++) {
if (i > 1)
put(' ');
for (arg = argv[i]; *arg != '\0'; arg++)
if (*arg == '\\') {
if ((arg = escape(arg)) == NULL)
goto printing_done;
} else
put(*arg);
}
put('\n');
printing_done:
if (fflush(stdout) == EOF)
/* LOCALIZE */
err(1, "Error writing to stdout");
return (0);
}
/*
* expand the first escape sequence that makes up the beginning of arg and
* print the expansion onto stdout. Return a pointer to the last character in
* the escape sequence, or NULL if the escape sequence is \c.
*/
static const char*
escape(const char *arg)
{
/* lookup table for escape sequences */
static const char esctab[] = {
['\\' - '\\'] = '\\',
['a' - '\\'] = '\a',
['b' - '\\'] = '\b',
['f' - '\\'] = '\f',
['n' - '\\'] = '\n',
['r' - '\\'] = '\r',
['v' - '\\'] = '\v',
};
int i, codepoint = 0;
++arg; /* assume *arg == '\\' */
/* *arg in esctab? */
if (*arg >= '\\' && *arg <= 'v' && esctab[*arg - '\\'] != 0) {
put(esctab[*arg - '\\']);
return (arg);
}
/* octal escape? */
if (*arg == '0') {
for (i = 0; i < 3; i++) {
++arg;
if ('0' <= *arg && *arg <= '7')
codepoint = codepoint * 8 + (*arg - '0');
else
break;
}
put(codepoint);
return (arg);
}
/* end of input? */
if (*arg == 'c')
return (NULL);
/* unknown escape */
put('\\');
put(*arg);
return (arg);
}
/*
* putchar() wrapped to exit the program on IO-error.
*/
static void
put(int c)
{
if (putchar(c) == EOF)
/* LOCALIZE */
err(1, "Error writing to stdout");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment