--- Makefile | 1 + tr.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 tr.c diff --git a/Makefile b/Makefile index 2a72a1c..b78ad2c 100644 --- a/Makefile +++ b/Makefile _AT_@ -81,6 +81,7 @@ SRC = \ tee.c \ test.c \ touch.c \ + tr.c \ true.c \ tty.c \ uname.c \ diff --git a/tr.c b/tr.c new file mode 100644 index 0000000..0053a52 --- /dev/null +++ b/tr.c _AT_@ -0,0 +1,117 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "text.h" +#include "util.h" + +static void +usage(void) +{ + eprintf("usage: tr set1 [set2]\n"); +} + +void +handle_escapes(char *s) +{ + switch(*s) { + case 'n': + *s = '\x0A'; + break; + case 't': + *s = '\x09'; + break; + case '\\': + *s = '\x5c'; + break; + } +} + +void +parse_mapping(char *set1, char *set2, char *mappings) +{ + char *s; + size_t n = 0; + size_t lset2; + + if(set2) { + lset2 = strnlen(set2, 255); + } else { + set2 = (char*) &set1[0]; + lset2 = 0; + } + + for(s = set1; *s; s++) { + if(*s == '\\') { + handle_escapes(++s); + ++n; + } + + mappings[(int) *s] = set2[n]; + if(n < (lset2 - 1)) + n++; + } +} + +void +map_to_null(const char *mappings, char *in) +{ + const char *s; + + for(s = in; *s; s++) { + if(!mappings[(int) *s]) + putchar((int) *s); + } +} + +void +map_to_set(const char *mappings, char *in) +{ + const char *s; + + for(s = in; *s; s++) { + if(!mappings[(int) *s]) { + putchar((int) *s); + } else { + putchar((int) mappings[(int) *s]); + } + } +} + +int +main(int argc, char *argv[]) +{ + char mappings[255]; + char *buf = NULL; + size_t size = 0; + void (*mapfunc) (const char*, char*); + + memset(mappings, 0, 255); + + ARGBEGIN { + default: + usage(); + } ARGEND; + + if(!argc) + usage(); + + if(argc >= 2) { + parse_mapping(argv[0], argv[1], mappings); + mapfunc = map_to_set; + } else { + parse_mapping(argv[0], NULL, mappings); + mapfunc = map_to_null; + } + + while(afgets(&buf, &size, stdin)) + mapfunc(mappings, buf); + + if (ferror(stdin)) { + eprintf("<stdin>: read error:"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} -- 1.8.4.2Received on Tue Nov 26 2013 - 21:01:01 CET
This archive was generated by hypermail 2.3.0 : Tue Nov 26 2013 - 21:12:21 CET