port of netbsd's tr

This commit is contained in:
Ben Gras 2010-04-08 15:08:31 +00:00
parent 1164052eea
commit c1bfcc9119
4 changed files with 67 additions and 49 deletions

View File

@ -813,6 +813,9 @@ touch: touch.c
top: top.c top: top.c
$(CCLD) -o $@ $< -lcurses $(CCLD) -o $@ $< -lcurses
tr: tr.c str.c
$(CCLD) -o $@ tr.c str.c
tsort: tsort.c tsort: tsort.c
$(CCLD) -o $@ $< $(CCLD) -o $@ $<
@install -S 4kw $@ @install -S 4kw $@
@ -1076,6 +1079,7 @@ install: \
/usr/bin/time \ /usr/bin/time \
/usr/bin/top \ /usr/bin/top \
/usr/bin/touch \ /usr/bin/touch \
/usr/bin/tr \
/usr/bin/truncate \ /usr/bin/truncate \
/usr/bin/tsort \ /usr/bin/tsort \
/usr/bin/ttt \ /usr/bin/ttt \
@ -1622,6 +1626,9 @@ install: \
/usr/bin/touch: touch /usr/bin/touch: touch
install -cs -o bin $> $@ install -cs -o bin $> $@
/usr/bin/tr: tr
install -cs -o bin $> $@
/usr/bin/truncate: truncate /usr/bin/truncate: truncate
install -cs -o bin $> $@ install -cs -o bin $> $@

View File

@ -29,14 +29,6 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)str.c 8.2 (Berkeley) 4/28/95";
#endif
__RCSID("$NetBSD: str.c,v 1.12 2009/04/13 23:50:49 lukem Exp $");
#endif /* not lint */
#include <sys/types.h> #include <sys/types.h>
#include <err.h> #include <err.h>
@ -47,15 +39,15 @@ __RCSID("$NetBSD: str.c,v 1.12 2009/04/13 23:50:49 lukem Exp $");
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "extern.h" #include "tr.h"
static int backslash __P((STR *)); static int backslash (STR *);
static int bracket __P((STR *)); static int bracket (STR *);
static int c_class __P((const void *, const void *)); static int c_class (const void *, const void *);
static void genclass __P((STR *)); static void genclass (STR *);
static void genequiv __P((STR *)); static void genequiv (STR *);
static int genrange __P((STR *)); static int genrange (STR *);
static void genseq __P((STR *)); static void genseq (STR *);
int int
next(s) next(s)
@ -122,21 +114,21 @@ bracket(s)
switch (s->str[1]) { switch (s->str[1]) {
case ':': /* "[:class:]" */ case ':': /* "[:class:]" */
if ((p = strstr(s->str + 2, ":]")) == NULL) if ((p = strstr((char *) s->str + 2, ":]")) == NULL)
return (0); return (0);
*p = '\0'; *p = '\0';
s->str += 2; s->str += 2;
genclass(s); genclass(s);
s->str = p + 2; s->str = (unsigned char *) p + 2;
return (1); return (1);
case '=': /* "[=equiv=]" */ case '=': /* "[=equiv=]" */
if ((p = strstr(s->str + 2, "=]")) == NULL) if ((p = strstr((char *) s->str + 2, "=]")) == NULL)
return (0); return (0);
s->str += 2; s->str += 2;
genequiv(s); genequiv(s);
return (1); return (1);
default: /* "[\###*n]" or "[#*n]" */ default: /* "[\###*n]" or "[#*n]" */
if ((p = strpbrk(s->str + 2, "*]")) == NULL) if ((p = strpbrk((char *) s->str + 2, "*]")) == NULL)
return (0); return (0);
if (p[0] != '*' || strchr(p, ']') == NULL) if (p[0] != '*' || strchr(p, ']') == NULL)
return (0); return (0);
@ -149,7 +141,7 @@ bracket(s)
typedef struct { typedef struct {
const char *name; const char *name;
int (*func) __P((int)); int (*func) (int);
int *set; int *set;
} CLASS; } CLASS;
@ -172,17 +164,21 @@ static void
genclass(s) genclass(s)
STR *s; STR *s;
{ {
int cnt, (*func) __P((int)); int cnt, (*func) (int);
CLASS *cp, tmp; CLASS *cp, tmp;
int *p; int *p;
tmp.name = s->str; tmp.name = (char *) s->str;
if ((cp = (CLASS *)bsearch(&tmp, classes, sizeof(classes) / if ((cp = (CLASS *)bsearch(&tmp, classes, sizeof(classes) /
sizeof(CLASS), sizeof(CLASS), c_class)) == NULL) sizeof(CLASS), sizeof(CLASS), c_class)) == NULL) {
errx(1, "unknown class %s", s->str); fprintf(stderr, "tr: unknown class %s\n", s->str);
exit(1);
}
if ((cp->set = p = malloc((NCHARS + 1) * sizeof(int))) == NULL) if ((cp->set = p = malloc((NCHARS + 1) * sizeof(int))) == NULL) {
err(1, "malloc"); perror("malloc");
exit(1);
}
memset(p, 0, (NCHARS + 1) * sizeof(int)); memset(p, 0, (NCHARS + 1) * sizeof(int));
for (cnt = 0, func = cp->func; cnt < NCHARS; ++cnt) for (cnt = 0, func = cp->func; cnt < NCHARS; ++cnt)
if ((func)(cnt)) if ((func)(cnt))
@ -211,12 +207,16 @@ genequiv(s)
{ {
if (*s->str == '\\') { if (*s->str == '\\') {
s->equiv[0] = backslash(s); s->equiv[0] = backslash(s);
if (*s->str != '=') if (*s->str != '=') {
errx(1, "misplaced equivalence equals sign"); fprintf(stderr, "tr: misplaced equivalence equals sign\n");
exit(1);
}
} else { } else {
s->equiv[0] = s->str[0]; s->equiv[0] = s->str[0];
if (s->str[1] != '=') if (s->str[1] != '=') {
errx(1, "misplaced equivalence equals sign"); fprintf(stderr, "tr: misplaced equivalence equals sign\n");
exit(1);
}
} }
s->str += 2; s->str += 2;
s->cnt = 0; s->cnt = 0;
@ -229,7 +229,7 @@ genrange(s)
STR *s; STR *s;
{ {
int stopval; int stopval;
char *savestart; unsigned char *savestart;
savestart = s->str; savestart = s->str;
stopval = *++s->str == '\\' ? backslash(s) : *s->str++; stopval = *++s->str == '\\' ? backslash(s) : *s->str++;
@ -249,15 +249,19 @@ genseq(s)
{ {
char *ep; char *ep;
if (s->which == STRING1) if (s->which == STRING1) {
errx(1, "sequences only valid in string2"); fprintf(stderr, "tr: sequences only valid in string2\n");
exit(1);
}
if (*s->str == '\\') if (*s->str == '\\')
s->lastch = backslash(s); s->lastch = backslash(s);
else else
s->lastch = *s->str++; s->lastch = *s->str++;
if (*s->str != '*') if (*s->str != '*') {
errx(1, "misplaced sequence asterisk"); fprintf(stderr, "tr: misplaced sequence asterisk\n");
exit(1);
}
switch (*++s->str) { switch (*++s->str) {
case '\\': case '\\':
@ -269,13 +273,14 @@ genseq(s)
break; break;
default: default:
if (isdigit(*s->str)) { if (isdigit(*s->str)) {
s->cnt = strtol(s->str, &ep, 0); s->cnt = strtol((char *) s->str, &ep, 0);
if (*ep == ']') { if (*ep == ']') {
s->str = ep + 1; s->str = (unsigned char *) ep + 1;
break; break;
} }
} }
errx(1, "illegal sequence count"); fprintf(stderr, "tr: illegal sequence count\n");
exit(1);
/* NOTREACHED */ /* NOTREACHED */
} }

View File

@ -29,18 +29,22 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#if 0
#include <sys/cdefs.h> #include <sys/cdefs.h>
#ifndef lint #ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1988, 1993\ __COPYRIGHT("@(#) Copyright (c) 1988, 1993\
The Regents of the University of California. All rights reserved."); The Regents of the University of California. All rights reserved.");
#endif /* not lint */ #endif /* not lint */
#endif
#if 0
#ifndef lint #ifndef lint
#if 0 #if 0
static char sccsid[] = "@(#)tr.c 8.2 (Berkeley) 5/4/95"; static char sccsid[] = "@(#)tr.c 8.2 (Berkeley) 5/4/95";
#endif #endif
__RCSID("$NetBSD: tr.c,v 1.8 2008/07/21 14:19:27 lukem Exp $"); __RCSID("$NetBSD: tr.c,v 1.8 2008/07/21 14:19:27 lukem Exp $");
#endif /* not lint */ #endif /* not lint */
#endif
#include <sys/types.h> #include <sys/types.h>
@ -50,7 +54,7 @@ __RCSID("$NetBSD: tr.c,v 1.8 2008/07/21 14:19:27 lukem Exp $");
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include "extern.h" #include "tr.h"
static int string1[NCHARS] = { static int string1[NCHARS] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* ASCII */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* ASCII */
@ -90,9 +94,9 @@ static int string1[NCHARS] = {
STR s1 = { STRING1, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL }; STR s1 = { STRING1, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
STR s2 = { STRING2, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL }; STR s2 = { STRING2, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
int main __P((int, char **)); int main (int, char **);
static void setup __P((int *, char *, STR *, int)); static void setup (int *, char *, STR *, int);
static void usage __P((void)); static void usage (void);
int int
main(argc, argv) main(argc, argv)
@ -194,15 +198,17 @@ main(argc, argv)
if (!isstring2) if (!isstring2)
usage(); usage();
s1.str = argv[0]; s1.str = (unsigned char *) argv[0];
s2.str = argv[1]; s2.str = (unsigned char *) argv[1];
if (cflag) if (cflag)
for (cnt = NCHARS, p = string1; cnt--;) for (cnt = NCHARS, p = string1; cnt--;)
*p++ = OOBCH; *p++ = OOBCH;
if (!next(&s2)) if (!next(&s2)) {
errx(1, "empty string2"); fprintf(stderr, "empty string2\n");
exit(1);
}
/* If string2 runs out of characters, use the last one specified. */ /* If string2 runs out of characters, use the last one specified. */
if (sflag) if (sflag)
@ -244,7 +250,7 @@ setup(string, arg, str, cflag)
{ {
int cnt, *p; int cnt, *p;
str->str = arg; str->str = (unsigned char *) arg;
memset(string, 0, NCHARS * sizeof(int)); memset(string, 0, NCHARS * sizeof(int));
while (next(str)) while (next(str))
string[str->lastch] = 1; string[str->lastch] = 1;

View File

@ -45,4 +45,4 @@ typedef struct {
#define NCHARS (UCHAR_MAX + 1) /* Number of possible characters. */ #define NCHARS (UCHAR_MAX + 1) /* Number of possible characters. */
#define OOBCH (UCHAR_MAX + 1) /* Out of band character value. */ #define OOBCH (UCHAR_MAX + 1) /* Out of band character value. */
int next __P((STR *)); int next (STR *);