* Copyright (c) 1988 The Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
"@(#) Copyright (c) 1988 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)tr.c 4.7 (Berkeley) 7/23/90";
#define NCHARS 256 /* size of u_char */
#define OOBCH 257 /* out of band value */
enum { NORM
, INRANGE
, EOS
} state
;
register int ch
, indx
, lastch
;
u_char
*tp
, tab
[NCHARS
], squeeze
[NCHARS
];
cflag
= dflag
= sflag
= 0;
while ((ch
= getopt(argc
, argv
, "cds")) != EOF
)
"usage: tr [-cds] [string1 [string2]]\n");
* the original tr was amazingly tolerant of the command line.
* Neither -c or -s have any effect unless there are two strings.
* Extra arguments are silently ignored. Bag this noise, they
if (argc
< 2 && !dflag
) {
while ((ch
= getchar()) != EOF
)
for (tp
= tab
, indx
= 0; indx
< NCHARS
; ++tp
, ++indx
)
for (lastch
= OOBCH
; (ch
= getchar()) != EOF
;) {
if (tab
[ch
] || (squeeze
[ch
] && lastch
== ch
))
while ((ch
= getchar()) != EOF
)
s1
.state
= s2
.state
= NORM
;
s1
.lastch
= s2
.lastch
= OOBCH
;
* if cflag is set, tr just pretends it only got one
* character in string2. As reasonable as anything
* else. Should really be an error.
for (tp
= tab
, indx
= 0; indx
< NCHARS
; ++tp
, ++indx
)
tab
[s1
.lastch
] = s1
.lastch
;
for (tp
= tab
, indx
= 0; indx
< NCHARS
; ++tp
, ++indx
)
tab
[s1
.lastch
] = s2
.lastch
;
for (lastch
= OOBCH
; (ch
= getchar()) != EOF
;) {
if (squeeze
[ch
] && lastch
== ch
)
while ((ch
= getchar()) != EOF
)
if (s
->state
== INRANGE
) {
if (++s
->lastch
== s
->endrange
)
if (ch
== '\\') { /* \### */
if (ch
== '-') { /* ranges */
if (s
->lastch
== OOBCH
) /* "-a" */
if (!(ch
= *s
->str
++)) /* "a-" */
if (ch
== '\\') /* \### */
if (s
->lastch
> ch
) { /* "z-a" */
if (s
->lastch
== ch
) /* "a-a" */
s
->state
= INRANGE
; /* "a-z" */
* Translate \-escapes. Up to 3 octal digits => char; no digits => literal.
* Unadorned backslash "\" is like \000.
register int ch
, cnt
= 0, val
= 0;
if (!isascii(ch
) || !isdigit(ch
) || ++cnt
> 3)
val
= val
* 8 + ch
- '0';