head	1.20;
access;
symbols
	netbsd-11-0-RC4:1.20
	netbsd-11-0-RC3:1.20
	netbsd-11-0-RC2:1.20
	netbsd-11-0-RC1:1.20
	perseant-exfatfs-base-20250801:1.20
	netbsd-11:1.20.0.40
	netbsd-11-base:1.20
	netbsd-10-1-RELEASE:1.20
	perseant-exfatfs-base-20240630:1.20
	perseant-exfatfs:1.20.0.38
	perseant-exfatfs-base:1.20
	netbsd-8-3-RELEASE:1.20
	netbsd-9-4-RELEASE:1.20
	netbsd-10-0-RELEASE:1.20
	netbsd-10-0-RC6:1.20
	netbsd-10-0-RC5:1.20
	netbsd-10-0-RC4:1.20
	netbsd-10-0-RC3:1.20
	netbsd-10-0-RC2:1.20
	netbsd-10-0-RC1:1.20
	netbsd-10:1.20.0.36
	netbsd-10-base:1.20
	netbsd-9-3-RELEASE:1.20
	cjep_sun2x-base1:1.20
	cjep_sun2x:1.20.0.34
	cjep_sun2x-base:1.20
	cjep_staticlib_x-base1:1.20
	netbsd-9-2-RELEASE:1.20
	cjep_staticlib_x:1.20.0.32
	cjep_staticlib_x-base:1.20
	netbsd-9-1-RELEASE:1.20
	phil-wifi-20200421:1.20
	phil-wifi-20200411:1.20
	is-mlppp:1.20.0.30
	is-mlppp-base:1.20
	phil-wifi-20200406:1.20
	netbsd-8-2-RELEASE:1.20
	netbsd-9-0-RELEASE:1.20
	netbsd-9-0-RC2:1.20
	netbsd-9-0-RC1:1.20
	phil-wifi-20191119:1.20
	netbsd-9:1.20.0.28
	netbsd-9-base:1.20
	phil-wifi-20190609:1.20
	netbsd-8-1-RELEASE:1.20
	netbsd-8-1-RC1:1.20
	pgoyette-compat-merge-20190127:1.20
	pgoyette-compat-20190127:1.20
	pgoyette-compat-20190118:1.20
	pgoyette-compat-1226:1.20
	pgoyette-compat-1126:1.20
	pgoyette-compat-1020:1.20
	pgoyette-compat-0930:1.20
	pgoyette-compat-0906:1.20
	netbsd-7-2-RELEASE:1.20
	pgoyette-compat-0728:1.20
	netbsd-8-0-RELEASE:1.20
	phil-wifi:1.20.0.26
	phil-wifi-base:1.20
	pgoyette-compat-0625:1.20
	netbsd-8-0-RC2:1.20
	pgoyette-compat-0521:1.20
	pgoyette-compat-0502:1.20
	pgoyette-compat-0422:1.20
	netbsd-8-0-RC1:1.20
	pgoyette-compat-0415:1.20
	pgoyette-compat-0407:1.20
	pgoyette-compat-0330:1.20
	pgoyette-compat-0322:1.20
	pgoyette-compat-0315:1.20
	netbsd-7-1-2-RELEASE:1.20
	pgoyette-compat:1.20.0.24
	pgoyette-compat-base:1.20
	netbsd-7-1-1-RELEASE:1.20
	matt-nb8-mediatek:1.20.0.22
	matt-nb8-mediatek-base:1.20
	perseant-stdc-iso10646:1.20.0.20
	perseant-stdc-iso10646-base:1.20
	netbsd-8:1.20.0.18
	netbsd-8-base:1.20
	prg-localcount2-base3:1.20
	prg-localcount2-base2:1.20
	prg-localcount2-base1:1.20
	prg-localcount2:1.20.0.16
	prg-localcount2-base:1.20
	pgoyette-localcount-20170426:1.20
	bouyer-socketcan-base1:1.20
	pgoyette-localcount-20170320:1.20
	netbsd-7-1:1.20.0.14
	netbsd-7-1-RELEASE:1.20
	netbsd-7-1-RC2:1.20
	netbsd-7-nhusb-base-20170116:1.20
	bouyer-socketcan:1.20.0.12
	bouyer-socketcan-base:1.20
	pgoyette-localcount-20170107:1.20
	netbsd-7-1-RC1:1.20
	pgoyette-localcount-20161104:1.20
	netbsd-7-0-2-RELEASE:1.20
	localcount-20160914:1.20
	netbsd-7-nhusb:1.20.0.10
	netbsd-7-nhusb-base:1.20
	pgoyette-localcount-20160806:1.20
	pgoyette-localcount-20160726:1.20
	pgoyette-localcount:1.20.0.8
	pgoyette-localcount-base:1.20
	netbsd-7-0-1-RELEASE:1.20
	netbsd-7-0:1.20.0.6
	netbsd-7-0-RELEASE:1.20
	netbsd-7-0-RC3:1.20
	netbsd-7-0-RC2:1.20
	netbsd-7-0-RC1:1.20
	netbsd-5-2-3-RELEASE:1.8
	netbsd-5-1-5-RELEASE:1.8
	netbsd-6-0-6-RELEASE:1.9
	netbsd-6-1-5-RELEASE:1.9
	netbsd-7:1.20.0.4
	netbsd-7-base:1.20
	yamt-pagecache-base9:1.20
	yamt-pagecache-tag8:1.9
	netbsd-6-1-4-RELEASE:1.9
	netbsd-6-0-5-RELEASE:1.9
	tls-earlyentropy:1.20.0.2
	tls-earlyentropy-base:1.20
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.20
	riastradh-drm2-base3:1.20
	netbsd-6-1-3-RELEASE:1.9
	netbsd-6-0-4-RELEASE:1.9
	netbsd-5-2-2-RELEASE:1.8
	netbsd-5-1-4-RELEASE:1.8
	netbsd-6-1-2-RELEASE:1.9
	netbsd-6-0-3-RELEASE:1.9
	netbsd-5-2-1-RELEASE:1.8
	netbsd-5-1-3-RELEASE:1.8
	netbsd-6-1-1-RELEASE:1.9
	riastradh-drm2-base2:1.9
	riastradh-drm2-base1:1.9
	riastradh-drm2:1.9.0.12
	riastradh-drm2-base:1.9
	netbsd-6-1:1.9.0.16
	netbsd-6-0-2-RELEASE:1.9
	netbsd-6-1-RELEASE:1.9
	netbsd-6-1-RC4:1.9
	netbsd-6-1-RC3:1.9
	agc-symver:1.9.0.14
	agc-symver-base:1.9
	netbsd-6-1-RC2:1.9
	netbsd-6-1-RC1:1.9
	yamt-pagecache-base8:1.9
	netbsd-5-2:1.8.0.2
	netbsd-6-0-1-RELEASE:1.9
	yamt-pagecache-base7:1.9
	netbsd-5-2-RELEASE:1.8
	netbsd-5-2-RC1:1.8
	matt-nb6-plus-nbase:1.9
	yamt-pagecache-base6:1.9
	netbsd-6-0:1.9.0.10
	netbsd-6-0-RELEASE:1.9
	netbsd-6-0-RC2:1.9
	tls-maxphys:1.9.0.8
	tls-maxphys-base:1.20
	matt-nb6-plus:1.9.0.6
	matt-nb6-plus-base:1.9
	netbsd-6-0-RC1:1.9
	yamt-pagecache-base5:1.9
	yamt-pagecache-base4:1.9
	netbsd-6:1.9.0.4
	netbsd-6-base:1.9
	netbsd-5-1-2-RELEASE:1.8
	netbsd-5-1-1-RELEASE:1.8
	yamt-pagecache-base3:1.9
	yamt-pagecache-base2:1.9
	yamt-pagecache:1.9.0.2
	yamt-pagecache-base:1.9
	cherry-xenmp:1.8.0.18
	cherry-xenmp-base:1.8
	bouyer-quota2-nbase:1.8
	bouyer-quota2:1.8.0.16
	bouyer-quota2-base:1.8
	matt-mips64-premerge-20101231:1.8
	matt-nb5-mips64-premerge-20101231:1.8
	matt-nb5-pq3:1.8.0.14
	matt-nb5-pq3-base:1.8
	netbsd-5-1:1.8.0.12
	netbsd-5-1-RELEASE:1.8
	netbsd-5-1-RC4:1.8
	matt-nb5-mips64-k15:1.8
	netbsd-5-1-RC3:1.8
	netbsd-5-1-RC2:1.8
	netbsd-5-1-RC1:1.8
	netbsd-5-0-2-RELEASE:1.8
	matt-nb5-mips64-premerge-20091211:1.8
	matt-premerge-20091211:1.8
	matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.8
	matt-nb4-mips64-k7-u2a-k9b:1.8
	matt-nb5-mips64-u1-k1-k5:1.8
	matt-nb5-mips64:1.8.0.10
	netbsd-5-0-1-RELEASE:1.8
	jym-xensuspend-nbase:1.8
	netbsd-5-0:1.8.0.8
	netbsd-5-0-RELEASE:1.8
	netbsd-5-0-RC4:1.8
	netbsd-5-0-RC3:1.8
	netbsd-5-0-RC2:1.8
	jym-xensuspend:1.8.0.6
	jym-xensuspend-base:1.8
	netbsd-5-0-RC1:1.8
	netbsd-5:1.8.0.4
	netbsd-5-base:1.8
	matt-mips64-base2:1.8
	matt-mips64:1.7.0.36
	netbsd-4-0-1-RELEASE:1.7
	wrstuden-revivesa-base-3:1.8
	wrstuden-revivesa-base-2:1.8
	wrstuden-fixsa-newbase:1.7
	wrstuden-revivesa-base-1:1.7
	yamt-pf42-base4:1.7
	yamt-pf42-base3:1.7
	hpcarm-cleanup-nbase:1.7
	yamt-pf42-baseX:1.7
	yamt-pf42-base2:1.7
	wrstuden-revivesa:1.7.0.34
	wrstuden-revivesa-base:1.7
	yamt-pf42:1.7.0.32
	yamt-pf42-base:1.7
	keiichi-mipv6-nbase:1.7
	keiichi-mipv6:1.7.0.30
	keiichi-mipv6-base:1.7
	matt-armv6-nbase:1.7
	matt-armv6-prevmlocking:1.7
	wrstuden-fixsa-base-1:1.7
	netbsd-4-0:1.7.0.28
	netbsd-4-0-RELEASE:1.7
	cube-autoconf:1.7.0.26
	cube-autoconf-base:1.7
	netbsd-4-0-RC5:1.7
	netbsd-4-0-RC4:1.7
	netbsd-4-0-RC3:1.7
	netbsd-4-0-RC2:1.7
	netbsd-4-0-RC1:1.7
	matt-armv6:1.7.0.24
	matt-armv6-base:1.7
	matt-mips64-base:1.7
	hpcarm-cleanup:1.7.0.22
	hpcarm-cleanup-base:1.7
	netbsd-3-1-1-RELEASE:1.7
	netbsd-3-0-3-RELEASE:1.7
	wrstuden-fixsa:1.7.0.20
	wrstuden-fixsa-base:1.7
	abandoned-netbsd-4-base:1.7
	abandoned-netbsd-4:1.7.0.14
	netbsd-3-1:1.7.0.16
	netbsd-3-1-RELEASE:1.7
	netbsd-3-0-2-RELEASE:1.7
	netbsd-3-1-RC4:1.7
	netbsd-3-1-RC3:1.7
	netbsd-3-1-RC2:1.7
	netbsd-3-1-RC1:1.7
	netbsd-4:1.7.0.18
	netbsd-4-base:1.7
	chap-midi-nbase:1.7
	netbsd-3-0-1-RELEASE:1.7
	chap-midi:1.7.0.12
	chap-midi-base:1.7
	netbsd-3-0:1.7.0.10
	netbsd-3-0-RELEASE:1.7
	netbsd-3-0-RC6:1.7
	netbsd-3-0-RC5:1.7
	netbsd-3-0-RC4:1.7
	netbsd-3-0-RC3:1.7
	netbsd-3-0-RC2:1.7
	netbsd-3-0-RC1:1.7
	netbsd-2-0-3-RELEASE:1.7
	netbsd-2-1:1.7.0.8
	netbsd-2-1-RELEASE:1.7
	netbsd-2-1-RC6:1.7
	netbsd-2-1-RC5:1.7
	netbsd-2-1-RC4:1.7
	netbsd-2-1-RC3:1.7
	netbsd-2-1-RC2:1.7
	netbsd-2-1-RC1:1.7
	netbsd-2-0-2-RELEASE:1.7
	netbsd-3:1.7.0.6
	netbsd-3-base:1.7
	netbsd-2-0-1-RELEASE:1.7
	netbsd-2:1.7.0.4
	netbsd-2-base:1.7
	netbsd-2-0-RELEASE:1.7
	netbsd-2-0-RC5:1.7
	netbsd-2-0-RC4:1.7
	netbsd-2-0-RC3:1.7
	netbsd-2-0-RC2:1.7
	netbsd-2-0-RC1:1.7
	netbsd-2-0:1.7.0.2
	netbsd-2-0-base:1.7
	netbsd-1-6-PATCH002-RELEASE:1.6
	netbsd-1-6-PATCH002:1.6
	netbsd-1-6-PATCH002-RC4:1.6
	netbsd-1-6-PATCH002-RC3:1.6
	netbsd-1-6-PATCH002-RC2:1.6
	netbsd-1-6-PATCH002-RC1:1.6
	netbsd-1-6-PATCH001:1.6
	netbsd-1-6-PATCH001-RELEASE:1.6
	netbsd-1-6-PATCH001-RC3:1.6
	netbsd-1-6-PATCH001-RC2:1.6
	netbsd-1-6-PATCH001-RC1:1.6
	fvdl_fs64_base:1.6
	netbsd-1-6-RELEASE:1.6
	netbsd-1-6-RC3:1.6
	netbsd-1-6-RC2:1.6
	netbsd-1-6-RC1:1.6
	netbsd-1-6:1.6.0.14
	netbsd-1-6-base:1.6
	netbsd-1-5-PATCH003:1.6
	netbsd-1-5-PATCH002:1.6
	netbsd-1-5-PATCH001:1.6
	netbsd-1-5-RELEASE:1.6
	netbsd-1-5-BETA2:1.6
	netbsd-1-5-BETA:1.6
	netbsd-1-4-PATCH003:1.6
	netbsd-1-5-ALPHA2:1.6
	netbsd-1-5:1.6.0.12
	netbsd-1-5-base:1.6
	minoura-xpg4dl-base:1.6
	minoura-xpg4dl:1.6.0.10
	netbsd-1-4-PATCH002:1.6
	wrstuden-devbsize-19991221:1.6
	wrstuden-devbsize:1.6.0.8
	wrstuden-devbsize-base:1.6
	comdex-fall-1999:1.6.0.6
	comdex-fall-1999-base:1.6
	netbsd-1-4-PATCH001:1.6
	netbsd-1-4-RELEASE:1.6
	netbsd-1-4:1.6.0.4
	netbsd-1-4-base:1.6
	netbsd-1-3-PATCH003:1.6
	netbsd-1-3-PATCH003-CANDIDATE2:1.6
	netbsd-1-3-PATCH003-CANDIDATE1:1.6
	netbsd-1-3-PATCH003-CANDIDATE0:1.6
	netbsd-1-3-PATCH002:1.6
	netbsd-1-3-PATCH001:1.6
	netbsd-1-3-RELEASE:1.6
	netbsd-1-3-BETA:1.6
	netbsd-1-3:1.6.0.2
	netbsd-1-3-base:1.6
	netbsd-1-2-PATCH001:1.5
	netbsd-1-2-RELEASE:1.5
	netbsd-1-2-BETA:1.5
	netbsd-1-2:1.5.0.6
	netbsd-1-2-base:1.5
	netbsd-1-1-PATCH001:1.5
	netbsd-1-1-RELEASE:1.5
	netbsd-1-1:1.5.0.2
	netbsd-1-1-base:1.5
	lite-2:1.1.1.3
	lite-1:1.1.1.2
	CSRG:1.1.1
	netbsd-1-0-PATCH06:1.3
	netbsd-1-0-PATCH05:1.3
	netbsd-1-0-PATCH04:1.3
	netbsd-1-0-PATCH03:1.3
	netbsd-1-0-PATCH02:1.3
	netbsd-1-0-PATCH1:1.3
	netbsd-1-0-PATCH0:1.3
	netbsd-1-0-RELEASE:1.3
	netbsd-1-0:1.3.0.2
	netbsd-1-0-base:1.3
	netbsd-0-9-RELEASE:1.2
	netbsd-0-9-BETA:1.2
	netbsd-0-9-ALPHA2:1.2
	netbsd-0-9-ALPHA:1.2
	netbsd-0-9:1.2.0.2
	netbsd-0-9-base:1.2
	netbsd-0-8:1.1.1.1
	netbsd-alpha-1:1.1.1.1
	patchkit-0-2-2:1.1.1.1
	WFJ-386bsd-01:1.1.1.1
	WFJ-920714:1.1.1;
locks; strict;
comment	@ * @;


1.20
date	2013.08.11.01.54.35;	author dholland;	state Exp;
branches;
next	1.19;
commitid	qN14ZFx1Fh2oEY0x;

1.19
date	2013.08.11.00.49.15;	author dholland;	state Exp;
branches;
next	1.18;
commitid	kmmyX3HmXAeWhY0x;

1.18
date	2013.08.11.00.48.37;	author dholland;	state Exp;
branches;
next	1.17;
commitid	Kx78tdx22IOHhY0x;

1.17
date	2013.08.11.00.39.22;	author dholland;	state Exp;
branches;
next	1.16;
commitid	nyp00kL9XfqzeY0x;

1.16
date	2013.08.11.00.34.09;	author dholland;	state Exp;
branches;
next	1.15;
commitid	uF097hT4S0DKcY0x;

1.15
date	2013.08.11.00.28.46;	author dholland;	state Exp;
branches;
next	1.14;
commitid	r0v5QXeiJM5taY0x;

1.14
date	2013.08.11.00.12.47;	author dholland;	state Exp;
branches;
next	1.13;
commitid	Bivzw5JtmAxr5Y0x;

1.13
date	2013.08.11.00.11.46;	author dholland;	state Exp;
branches;
next	1.12;
commitid	xsnofsLfzmlU4Y0x;

1.12
date	2013.08.11.00.05.49;	author dholland;	state Exp;
branches;
next	1.11;
commitid	Cb46uVlDqAN33Y0x;

1.11
date	2013.08.11.00.04.14;	author dholland;	state Exp;
branches;
next	1.10;
commitid	Ogr2CaK2QgBp2Y0x;

1.10
date	2013.08.10.23.54.41;	author dholland;	state Exp;
branches;
next	1.9;
commitid	14Saw7fwCNndZX0x;

1.9
date	2011.09.06.18.33.46;	author joerg;	state Exp;
branches
	1.9.2.1
	1.9.8.1;
next	1.8;

1.8
date	2008.07.21.14.19.27;	author lukem;	state Exp;
branches;
next	1.7;

1.7
date	2003.08.07.11.16.47;	author agc;	state Exp;
branches
	1.7.34.1;
next	1.6;

1.6
date	97.10.20.00.56.06;	author lukem;	state Exp;
branches;
next	1.5;

1.5
date	95.08.31.22.13.48;	author jtc;	state Exp;
branches;
next	1.4;

1.4
date	94.12.07.08.35.17;	author jtc;	state Exp;
branches;
next	1.3;

1.3
date	93.08.01.18.04.34;	author mycroft;	state Exp;
branches;
next	1.2;

1.2
date	93.04.27.04.52.30;	author glass;	state Exp;
branches;
next	1.1;

1.1
date	93.03.21.09.45.37;	author cgd;	state Exp;
branches
	1.1.1.1;
next	;

1.9.2.1
date	2014.05.22.11.42.51;	author yamt;	state Exp;
branches;
next	;
commitid	cG7DCbrDdiE9MwBx;

1.9.8.1
date	2014.08.20.00.05.05;	author tls;	state Exp;
branches;
next	;
commitid	jTnpym9Qu0o4R1Nx;

1.7.34.1
date	2008.09.18.04.29.24;	author wrstuden;	state Exp;
branches;
next	;

1.1.1.1
date	93.03.21.09.45.37;	author cgd;	state Exp;
branches;
next	1.1.1.2;

1.1.1.2
date	94.12.07.05.11.50;	author jtc;	state Exp;
branches;
next	1.1.1.3;

1.1.1.3
date	95.08.31.22.11.50;	author jtc;	state Exp;
branches;
next	;


desc
@@


1.20
log
@Whitespace.
@
text
@/*	$NetBSD: tr.c,v 1.19 2013/08/11 00:49:15 dholland Exp $	*/

/*
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 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. 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
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@@(#) Copyright (c) 1988, 1993\
 The Regents of the University of California.  All rights reserved.");
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@@(#)tr.c	8.2 (Berkeley) 5/4/95";
#endif
__RCSID("$NetBSD: tr.c,v 1.19 2013/08/11 00:49:15 dholland Exp $");
#endif /* not lint */

#include <sys/types.h>

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "extern.h"

static int string1[NCHARS], string2[NCHARS];

static void setup(int *, const char *, int, int);
__dead static void usage(void);

int
main(int argc, char **argv)
{
	int ch, ch2, lastch;
	int cflag, dflag, sflag, isstring2;
	STR *s1, *s2;

	cflag = dflag = sflag = 0;
	while ((ch = getopt(argc, argv, "cds")) != -1)
		switch (ch) {
		case 'c':
			cflag = 1;
			break;
		case 'd':
			dflag = 1;
			break;
		case 's':
			sflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	switch(argc) {
	case 0:
	default:
		usage();
		/* NOTREACHED */
	case 1:
		isstring2 = 0;
		break;
	case 2:
		isstring2 = 1;
		break;
	}

	/*
	 * tr -ds [-c] string1 string2
	 * Delete all characters (or complemented characters) in string1.
	 * Squeeze all characters in string2.
	 */
	if (dflag && sflag) {
		if (!isstring2)
			usage();

		setup(string1, argv[0], 1, cflag);
		setup(string2, argv[1], 2, 0);

		for (lastch = OOBCH; (ch = getchar()) != EOF; )
			if (!string1[ch] && (!string2[ch] || lastch != ch)) {
				lastch = ch;
				(void)putchar(ch);
			}
		exit(0);
	}

	/*
	 * tr -d [-c] string1
	 * Delete all characters (or complemented characters) in string1.
	 */
	if (dflag) {
		if (isstring2)
			usage();

		setup(string1, argv[0], 1, cflag);

		while ((ch = getchar()) != EOF)
			if (!string1[ch])
				(void)putchar(ch);
		exit(0);
	}

	/*
	 * tr -s [-c] string1
	 * Squeeze all characters (or complemented characters) in string1.
	 */
	if (sflag && !isstring2) {
		setup(string1, argv[0], 1, cflag);

		for (lastch = OOBCH; (ch = getchar()) != EOF;)
			if (!string1[ch] || lastch != ch) {
				lastch = ch;
				(void)putchar(ch);
			}
		exit(0);
	}

	/*
	 * tr [-cs] string1 string2
	 * Replace all characters (or complemented characters) in string1 with
	 * the character in the same position in string2.  If the -s option is
	 * specified, squeeze all the characters in string2.
	 */
	if (!isstring2)
		usage();

	/*
	 * The first and second strings need to be matched up. This
	 * means that if we are doing -c, we need to scan the first
	 * string in advance, complement it, and match *that* against
	 * the second string; otherwise we need to scan them together.
	 */

	if (cflag) {
		/*
		 * Scan string 1 and complement it. After this,
		 * string1[] contains 0 for chars to leave alone and 1
		 * for chars to translate.
		 */
		setup(string1, argv[0], 1, cflag);
		s1 = NULL; /* for safety */
		/* we will use ch to iterate over string1, so start it */
		ch = -1;
	} else {
		/* Create the scanner for string 1. */
		s1 = str_create(1, argv[0]);
		for (ch = 0; ch < NCHARS; ch++) {
			string1[ch] = ch;
		}
	}
	/* Create the scanner for string 2. */
	s2 = str_create(2, argv[1]);

	/* Read the first char of string 2 first to make sure there is one. */
	if (!next(s2, &ch2))
		errx(1, "empty string2");

	/*
	 * Loop over the chars from string 1. After this loop string1[]
	 * is a mapping from input to output chars.
	 */
	while (1) {
		if (cflag) {
			/*
			 * Try each character in order. For characters we
			 * skip over because we aren't translating them,
			 * set the translation to the identity.
			 */
			ch++;
			while (ch < NCHARS && string1[ch] == 0) {
				if (string1[ch] == 0) {
					string1[ch] = ch;
				}
				ch++;
			}
			if (ch == NCHARS) {
				break;
			}
		}
		else {
			/* Get the next character from string 1. */
			if (!next(s1, &ch)) {
				break;
			}
		}

		/* Set the translation to the character from string 2. */
		string1[ch] = ch2;

		/* Note the characters to squeeze in string2[]. */
		if (sflag) {
			string2[ch2] = 1;
		}

		/*
		 * Get the next character from string 2. If it runs
		 * out, this will keep returning the last character
		 * over and over again.
		 */
		(void)next(s2, &ch2);
	}

	/*
	 * Now do it.
	 */

	if (sflag)
		for (lastch = OOBCH; (ch = getchar()) != EOF;) {
			ch = string1[ch];
			if (!string2[ch] || lastch != ch) {
				lastch = ch;
				(void)putchar(ch);
			}
		}
	else
		while ((ch = getchar()) != EOF)
			(void)putchar(string1[ch]);

	/* Clean up and exit. */
	if (s1 != NULL) {
		str_destroy(s1);
	}
	str_destroy(s2);
	exit (0);
}

static void
setup(int *string, const char *arg, int whichstring, int cflag)
{
	int cnt, *p;
	int ch;
	STR *str;

	str = str_create(whichstring, arg);
	while (next(str, &ch))
		string[ch] = 1;
	if (cflag)
		for (p = string, cnt = NCHARS; cnt--; ++p)
			*p = !*p;
	str_destroy(str);
}

static void
usage(void)
{
	(void)fprintf(stderr, "usage: tr [-cs] string1 string2\n");
	(void)fprintf(stderr, "       tr [-c] -d string1\n");
	(void)fprintf(stderr, "       tr [-c] -s string1\n");
	(void)fprintf(stderr, "       tr [-c] -ds string1 string2\n");
	exit(1);
}
@


1.19
log
@Don't explicitly zero bss variables that are already zeroed.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.18 2013/08/11 00:48:37 dholland Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.18 2013/08/11 00:48:37 dholland Exp $");
d110 2
a111 2
		
		for (lastch = OOBCH; (ch = getchar()) != EOF;)
@


1.18
log
@Add comments explaining how this works.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.17 2013/08/11 00:39:22 dholland Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.17 2013/08/11 00:39:22 dholland Exp $");
a266 1
	memset(string, 0, NCHARS * sizeof(int));
@


1.17
log
@Simplify the parser handling.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.16 2013/08/11 00:34:09 dholland Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.16 2013/08/11 00:34:09 dholland Exp $");
d159 7
d167 5
d174 1
d177 1
d183 1
d186 1
d190 4
a193 1
	/* If string2 runs out of characters, use the last one specified. */
d196 5
d213 1
d219 1
d221 2
d226 6
d235 4
d251 1
@


1.16
log
@Remove silly written-out initialization of string1.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.15 2013/08/11 00:28:46 dholland Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.15 2013/08/11 00:28:46 dholland Exp $");
d57 1
a57 1
static void setup(int *, const char *, STR *, int);
a98 3
	s1 = str_create(1);
	s2 = str_create(2);

d108 2
a109 2
		setup(string1, argv[0], s1, cflag);
		setup(string2, argv[1], s2, 0);
a115 2
		str_destroy(s1);
		str_destroy(s2);
d127 1
a127 1
		setup(string1, argv[0], s1, cflag);
a131 2
		str_destroy(s1);
		str_destroy(s2);
d140 1
a140 1
		setup(string1, argv[0], s1, cflag);
a146 2
		str_destroy(s1);
		str_destroy(s2);
d160 2
a161 1
		setup(string1, argv[0], s1, cflag);
d164 1
a164 1
		str_setstring(s1, argv[0]);
d169 1
a169 1
	str_setstring(s2, argv[1]);
d213 3
a215 1
	str_destroy(s1);
d221 1
a221 1
setup(int *string, const char *arg, STR *str, int cflag)
d225 1
d227 1
a227 1
	str_setstring(str, arg);
d234 1
@


1.15
log
@Make tr -c work. Fixes PR 48113.

When -c is in effect, scan string1 first, complement it, and then
iterate over the results while scanning string2. Otherwise, scan
string1 and string2 together as before.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.14 2013/08/11 00:12:47 dholland Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.14 2013/08/11 00:12:47 dholland Exp $");
d55 1
a55 34
static int string1[NCHARS] = {
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,		/* ASCII */
	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
}, string2[NCHARS];
d173 3
@


1.14
log
@apply some CSE
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.12 2013/08/11 00:05:49 dholland Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.12 2013/08/11 00:05:49 dholland Exp $");
d96 1
a96 1
	int ch, ch2, cnt, lastch, *p;
d201 6
a206 1
	str_setstring(s1, argv[0]);
a208 4
	if (cflag)
		for (cnt = NCHARS, p = string1; cnt--;)
			*p++ = OOBCH;

d213 19
a231 1
	while (next(s1, &ch)) {
a238 4
	if (cflag)
		for (cnt = 0, p = string1; cnt < NCHARS; ++p, ++cnt)
			*p = *p == OOBCH ? ch2 : cnt;

d250 1
@


1.13
log
@Restore preexisting wrong behavior of tr -c (translates all characters
to the last letter in string2) instead of a different wrong behavior
(translates all characters to 0xff) accidentally just introduced.
@
text
@d212 3
a214 3
	if (sflag)
		while (next(s1, &ch)) {
			string1[ch] = ch2;
a215 6
			(void)next(s2, &ch2);
		}
	else
		while (next(s1, &ch)) {
			string1[ch] = ch2;
			(void)next(s2, &ch2);
d217 2
@


1.12
log
@sprinkle const
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.11 2013/08/11 00:04:14 dholland Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.11 2013/08/11 00:04:14 dholland Exp $");
d226 1
a226 1
			*p = *p == OOBCH ? ch : cnt;
@


1.11
log
@Make the parser state opaque. While here, fix a memory leak when using
the [:foo:] syntax.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.10 2013/08/10 23:54:41 dholland Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.10 2013/08/10 23:54:41 dholland Exp $");
d90 1
a90 1
static void setup(int *, char *, STR *, int);
d245 1
a245 1
setup(int *string, char *arg, STR *str, int cflag)
@


1.10
log
@Expose less of the parser state outside str.c.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.9 2011/09/06 18:33:46 joerg Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.9 2011/09/06 18:33:46 joerg Exp $");
a89 3
STR s1 = { STRING1, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
STR s2 = { STRING2, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };

d98 1
d132 3
d144 2
a145 2
		setup(string1, argv[0], &s1, cflag);
		setup(string2, argv[1], &s2, 0);
d152 2
d165 1
a165 1
		setup(string1, argv[0], &s1, cflag);
d170 2
d180 1
a180 1
		setup(string1, argv[0], &s1, cflag);
d187 2
d201 2
a202 2
	s1.str = argv[0];
	s2.str = argv[1];
d208 1
a208 1
	if (!next(&s2, &ch2))
d213 1
a213 1
		while (next(&s1, &ch)) {
d216 1
a216 1
			(void)next(&s2, &ch2);
d219 1
a219 1
		while (next(&s1, &ch)) {
d221 1
a221 1
			(void)next(&s2, &ch2);
d239 2
d250 1
a250 1
	str->str = arg;
@


1.9
log
@ANSIfy. Sprinkle const and __dead.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.8 2008/07/21 14:19:27 lukem Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.8 2008/07/21 14:19:27 lukem Exp $");
d99 1
a99 1
	int ch, cnt, lastch, *p;
d104 1
a104 1
		switch((char)ch) {
d201 1
a201 1
	if (!next(&s2))
d206 4
a209 4
		while (next(&s1)) {
			string1[s1.lastch] = ch = s2.lastch;
			string2[ch] = 1;
			(void)next(&s2);
d212 3
a214 3
		while (next(&s1)) {
			string1[s1.lastch] = ch = s2.lastch;
			(void)next(&s2);
d239 1
d243 2
a244 2
	while (next(str))
		string[str->lastch] = 1;
@


1.9.8.1
log
@Rebase to HEAD as of a few days ago.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d42 1
a42 1
__RCSID("$NetBSD$");
d55 34
a88 1
static int string1[NCHARS], string2[NCHARS];
d90 4
a93 1
static void setup(int *, const char *, int, int);
d99 1
a99 1
	int ch, ch2, lastch;
a100 1
	STR *s1, *s2;
d104 1
a104 1
		switch (ch) {
d143 4
a146 4
		setup(string1, argv[0], 1, cflag);
		setup(string2, argv[1], 2, 0);

		for (lastch = OOBCH; (ch = getchar()) != EOF; )
d162 1
a162 1
		setup(string1, argv[0], 1, cflag);
d175 1
a175 1
		setup(string1, argv[0], 1, cflag);
d194 2
a195 6
	/*
	 * The first and second strings need to be matched up. This
	 * means that if we are doing -c, we need to scan the first
	 * string in advance, complement it, and match *that* against
	 * the second string; otherwise we need to scan them together.
	 */
d197 3
a199 19
	if (cflag) {
		/*
		 * Scan string 1 and complement it. After this,
		 * string1[] contains 0 for chars to leave alone and 1
		 * for chars to translate.
		 */
		setup(string1, argv[0], 1, cflag);
		s1 = NULL; /* for safety */
		/* we will use ch to iterate over string1, so start it */
		ch = -1;
	} else {
		/* Create the scanner for string 1. */
		s1 = str_create(1, argv[0]);
		for (ch = 0; ch < NCHARS; ch++) {
			string1[ch] = ch;
		}
	}
	/* Create the scanner for string 2. */
	s2 = str_create(2, argv[1]);
d201 1
a201 2
	/* Read the first char of string 2 first to make sure there is one. */
	if (!next(s2, &ch2))
d204 6
a209 21
	/*
	 * Loop over the chars from string 1. After this loop string1[]
	 * is a mapping from input to output chars.
	 */
	while (1) {
		if (cflag) {
			/*
			 * Try each character in order. For characters we
			 * skip over because we aren't translating them,
			 * set the translation to the identity.
			 */
			ch++;
			while (ch < NCHARS && string1[ch] == 0) {
				if (string1[ch] == 0) {
					string1[ch] = ch;
				}
				ch++;
			}
			if (ch == NCHARS) {
				break;
			}
d211 4
a214 5
		else {
			/* Get the next character from string 1. */
			if (!next(s1, &ch)) {
				break;
			}
d217 3
a219 19
		/* Set the translation to the character from string 2. */
		string1[ch] = ch2;

		/* Note the characters to squeeze in string2[]. */
		if (sflag) {
			string2[ch2] = 1;
		}

		/*
		 * Get the next character from string 2. If it runs
		 * out, this will keep returning the last character
		 * over and over again.
		 */
		(void)next(s2, &ch2);
	}

	/*
	 * Now do it.
	 */
a231 6

	/* Clean up and exit. */
	if (s1 != NULL) {
		str_destroy(s1);
	}
	str_destroy(s2);
d236 1
a236 1
setup(int *string, const char *arg, int whichstring, int cflag)
a238 2
	int ch;
	STR *str;
d240 4
a243 3
	str = str_create(whichstring, arg);
	while (next(str, &ch))
		string[ch] = 1;
a246 1
	str_destroy(str);
@


1.9.2.1
log
@sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs.  ("Protocol error: too many arguments")
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.9 2011/09/06 18:33:46 joerg Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.9 2011/09/06 18:33:46 joerg Exp $");
d55 34
a88 1
static int string1[NCHARS], string2[NCHARS];
d90 4
a93 1
static void setup(int *, const char *, int, int);
d99 1
a99 1
	int ch, ch2, lastch;
a100 1
	STR *s1, *s2;
d104 1
a104 1
		switch (ch) {
d143 4
a146 4
		setup(string1, argv[0], 1, cflag);
		setup(string2, argv[1], 2, 0);

		for (lastch = OOBCH; (ch = getchar()) != EOF; )
d162 1
a162 1
		setup(string1, argv[0], 1, cflag);
d175 1
a175 1
		setup(string1, argv[0], 1, cflag);
d194 2
a195 6
	/*
	 * The first and second strings need to be matched up. This
	 * means that if we are doing -c, we need to scan the first
	 * string in advance, complement it, and match *that* against
	 * the second string; otherwise we need to scan them together.
	 */
d197 3
a199 19
	if (cflag) {
		/*
		 * Scan string 1 and complement it. After this,
		 * string1[] contains 0 for chars to leave alone and 1
		 * for chars to translate.
		 */
		setup(string1, argv[0], 1, cflag);
		s1 = NULL; /* for safety */
		/* we will use ch to iterate over string1, so start it */
		ch = -1;
	} else {
		/* Create the scanner for string 1. */
		s1 = str_create(1, argv[0]);
		for (ch = 0; ch < NCHARS; ch++) {
			string1[ch] = ch;
		}
	}
	/* Create the scanner for string 2. */
	s2 = str_create(2, argv[1]);
d201 1
a201 2
	/* Read the first char of string 2 first to make sure there is one. */
	if (!next(s2, &ch2))
d204 6
a209 21
	/*
	 * Loop over the chars from string 1. After this loop string1[]
	 * is a mapping from input to output chars.
	 */
	while (1) {
		if (cflag) {
			/*
			 * Try each character in order. For characters we
			 * skip over because we aren't translating them,
			 * set the translation to the identity.
			 */
			ch++;
			while (ch < NCHARS && string1[ch] == 0) {
				if (string1[ch] == 0) {
					string1[ch] = ch;
				}
				ch++;
			}
			if (ch == NCHARS) {
				break;
			}
d211 4
a214 5
		else {
			/* Get the next character from string 1. */
			if (!next(s1, &ch)) {
				break;
			}
d217 3
a219 19
		/* Set the translation to the character from string 2. */
		string1[ch] = ch2;

		/* Note the characters to squeeze in string2[]. */
		if (sflag) {
			string2[ch2] = 1;
		}

		/*
		 * Get the next character from string 2. If it runs
		 * out, this will keep returning the last character
		 * over and over again.
		 */
		(void)next(s2, &ch2);
	}

	/*
	 * Now do it.
	 */
a231 6

	/* Clean up and exit. */
	if (s1 != NULL) {
		str_destroy(s1);
	}
	str_destroy(s2);
d236 1
a236 1
setup(int *string, const char *arg, int whichstring, int cflag)
a238 2
	int ch;
	STR *str;
d240 4
a243 3
	str = str_create(whichstring, arg);
	while (next(str, &ch))
		string[ch] = 1;
a246 1
	str_destroy(str);
@


1.8
log
@Remove the \n and tabs from the __COPYRIGHT() strings.
Tweak to use a consistent format.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.7 2003/08/07 11:16:47 agc Exp $	*/
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.7 2003/08/07 11:16:47 agc Exp $");
d93 2
a94 3
int	main __P((int, char **));
static void setup __P((int *, char *, STR *, int));
static void usage __P((void));
d97 1
a97 3
main(argc, argv)
	int argc;
	char **argv;
d236 1
a236 5
setup(string, arg, str, cflag)
	int *string;
	char *arg;
	STR *str;
	int cflag;
d250 1
a250 1
usage()
@


1.7
log
@Move UCB-licensed code from 4-clause to 3-clause licence.

Patches provided by Joel Baker in PR 22365, verified by myself.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.6 1997/10/20 00:56:06 lukem Exp $	*/
d34 2
a35 2
__COPYRIGHT("@@(#) Copyright (c) 1988, 1993\n\
	The Regents of the University of California.  All rights reserved.\n");
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.6 1997/10/20 00:56:06 lukem Exp $");
@


1.7.34.1
log
@Sync with wrstuden-revivesa-base-2.
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.7 2003/08/07 11:16:47 agc Exp $	*/
d34 2
a35 2
__COPYRIGHT("@@(#) Copyright (c) 1988, 1993\
 The Regents of the University of California.  All rights reserved.");
d42 1
a42 1
__RCSID("$NetBSD: tr.c,v 1.7 2003/08/07 11:16:47 agc Exp $");
@


1.6
log
@WARNSify, fix .Nm usage, getopt returns -1 not EOF, use <err.h>
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.5 1995/08/31 22:13:48 jtc Exp $	*/
d15 1
a15 5
 * 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
d42 1
a42 1
__RCSID("$NetBSD$");
@


1.5
log
@Sync with 4.4lite2
@
text
@d1 1
a1 1
/*	$NetBSD: tr.c,v 1.4 1994/12/07 08:35:17 jtc Exp $	*/
d36 1
d38 2
a39 3
static char copyright[] =
"@@(#) Copyright (c) 1988, 1993\n\
	The Regents of the University of California.  All rights reserved.\n";
d46 1
a46 1
static char rcsid[] = "$NetBSD: tr.c,v 1.4 1994/12/07 08:35:17 jtc Exp $";
d51 1
d97 1
d106 1
a106 1
	register int ch, cnt, lastch, *p;
d110 1
a110 1
	while ((ch = getopt(argc, argv, "cds")) != EOF)
d209 1
a209 1
		err("empty string2");
d249 1
a249 1
	register int cnt, *p;
d252 1
a252 1
	bzero(string, NCHARS * sizeof(int));
a267 29
}

#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif

void
#if __STDC__
err(const char *fmt, ...)
#else
err(fmt, va_alist)
	char *fmt;
        va_dcl
#endif
{
	va_list ap;
#if __STDC__
	va_start(ap, fmt);
#else
	va_start(ap);
#endif
	(void)fprintf(stderr, "tr: ");
	(void)vfprintf(stderr, fmt, ap);
	va_end(ap);
	(void)fprintf(stderr, "\n");
	exit(1);
	/* NOTREACHED */
@


1.4
log
@Merged with 4.4lite.
Changed to conform to NetBSD's new RCS Id convention.
@
text
@d1 1
a1 1
/*	$NetBSD: $	*/
d44 1
a44 1
static char sccsid[] = "@@(#)tr.c	8.1 (Berkeley) 6/6/93";
d46 1
a46 1
static char rcsid[] = "$NetBSD: $";
d50 1
d54 2
@


1.3
log
@Add RCS identifiers.
@
text
@d1 2
d4 2
a5 2
 * Copyright (c) 1988 The Regents of the University of California.
 * All rights reserved.
d37 3
a39 3
char copyright[] =
"@@(#) Copyright (c) 1988 The Regents of the University of California.\n\
 All rights reserved.\n";
d43 4
a46 2
/*static char sccsid[] = "from: @@(#)tr.c	5.4 (Berkeley) 3/3/93";*/
static char rcsid[] = "$Id: $";
@


1.2
log
@integrated updated 'tr' from ftp.uu.net:bsd-sources
@
text
@d41 2
a42 1
static char sccsid[] = "@@(#)tr.c	5.4 (Berkeley) 3/3/93";
@


1.1
log
@Initial revision
@
text
@d41 1
a41 1
static char sccsid[] = "@@(#)tr.c	4.7 (Berkeley) 7/23/90";
d46 38
a83 1
#include <ctype.h>
d85 2
a86 2
#define	NCHARS	256				/* size of u_char */
#define	OOBCH	257				/* out of band value */
d88 2
a89 5
typedef struct {
	char *str;
	int lastch, endrange;
	enum { NORM, INRANGE, EOS } state;
} STR;
d91 1
d96 2
a97 5
	extern int optind;
	STR s1, s2;
	register int ch, indx, lastch;
	int cflag, dflag, sflag;
	u_char *tp, tab[NCHARS], squeeze[NCHARS];
d113 1
a113 3
			fprintf(stderr,
			    "usage: tr [-cds] [string1 [string2]]\n");
			exit(1);
d118 33
d152 2
a153 4
	 * 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
	 * should all be errors.
d155 6
a160 1
	if (argc < 2 && !dflag) {
d162 2
a163 1
			putchar(ch);
d167 9
a175 21
	bzero(tab, NCHARS);
	if (sflag) {
		s1.str = argv[1];
		s1.state = NORM;
		s1.lastch = OOBCH;
		while (next(&s1))
			squeeze[s1.lastch] = 1;
	}
	if (dflag) {
		s1.str = argv[0];
		s1.state = NORM;
		s1.lastch = OOBCH;
		while (next(&s1))
			tab[s1.lastch] = 1;
		if (cflag)
			for (tp = tab, indx = 0; indx < NCHARS; ++tp, ++indx)
				*tp = !*tp;
		if (sflag)
			for (lastch = OOBCH; (ch = getchar()) != EOF;) {
				if (tab[ch] || (squeeze[ch] && lastch == ch))
					continue;
d177 1
a177 1
				putchar(ch);
d179 33
a211 28
		else
			while ((ch = getchar()) != EOF)
				if (!tab[ch])
					putchar(ch);
	} else {
		s1.str = argv[0];
		s2.str = argv[1];
		s1.state = s2.state = NORM;
		s1.lastch = s2.lastch = OOBCH;
		if (cflag) {
			/*
			 * if cflag is set, tr just pretends it only got one
			 * character in string2.  As reasonable as anything
			 * else.  Should really be an error.
			 */
			while (next(&s2));
			lastch = s2.lastch;
			for (tp = tab, indx = 0; indx < NCHARS; ++tp, ++indx)
				*tp = lastch;
			while (next(&s1))
				tab[s1.lastch] = s1.lastch;
		} else {
			for (tp = tab, indx = 0; indx < NCHARS; ++tp, ++indx)
				*tp = indx;
			while (next(&s1)) {
				(void)next(&s2);
				tab[s1.lastch] = s2.lastch;
			}
d213 9
a221 5
		if (sflag)
			for (lastch = OOBCH; (ch = getchar()) != EOF;) {
				ch = tab[ch];
				if (squeeze[ch] && lastch == ch)
					continue;
d223 1
a223 1
				putchar(ch);
d225 5
a229 5
		else
			while ((ch = getchar()) != EOF)
				putchar((int)tab[ch]);
	}
	exit(0);
d232 6
a237 2
next(s)
	register STR *s;
d239 1
a239 1
	register int ch;
d241 7
a247 35
	if (s->state == EOS)
		return(0);
	if (s->state == INRANGE) {
		if (++s->lastch == s->endrange)
			s->state = NORM;
		return(1);
	}
	if (!(ch = *s->str++)) {
		s->state = EOS;
		return(0);
	}
	if (ch == '\\') {			/* \### */
		s->lastch = tran(s);
		return(1);
	}
	if (ch == '-') {			/* ranges */
		if (s->lastch == OOBCH)		/* "-a" */
			goto fail2;
		if (!(ch = *s->str++))		/* "a-" */
			goto fail1;
		if (ch == '\\')			/* \### */
			ch = tran(s);
		if (s->lastch > ch) { 		/* "z-a" */
fail1:			--s->str;
fail2:			s->lastch = '-';
			return(1);
		}
		if (s->lastch == ch)		/* "a-a" */
			return(next(s));
		s->state = INRANGE;		/* "a-z" */
		s->endrange = ch;
		return(1);
	}
	s->lastch = ch;
	return(1);
d250 2
a251 6
/*
 * Translate \-escapes.  Up to 3 octal digits => char; no digits => literal.
 * Unadorned backslash "\" is like \000.
 */
tran(s)
	register STR *s;
d253 6
a258 1
	register int ch, cnt = 0, val = 0;
d260 27
a286 9
	for (;;) {
		ch = *s->str++;
		if (!isascii(ch) || !isdigit(ch) || ++cnt > 3)
			break;
		val = val * 8 + ch - '0';
	}
	if (cnt || ch == 0)
		s->str--;
	return (cnt ? val : ch);
@


1.1.1.1
log
@initial import of 386bsd-0.1 sources
@
text
@@


1.1.1.2
log
@imported from 4.4lite
@
text
@d2 2
a3 2
 * Copyright (c) 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
d35 3
a37 3
static char copyright[] =
"@@(#) Copyright (c) 1988, 1993\n\
	The Regents of the University of California.  All rights reserved.\n";
d41 1
a41 1
static char sccsid[] = "@@(#)tr.c	8.1 (Berkeley) 6/6/93";
d46 1
a46 38
#include <stdlib.h>
#include <string.h>
#include "extern.h"

static int string1[NCHARS] = {
	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,		/* ASCII */
	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
}, string2[NCHARS];
d48 2
a49 2
STR s1 = { STRING1, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
STR s2 = { STRING2, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
d51 5
a55 2
static void setup __P((int *, char *, STR *, int));
static void usage __P((void));
a56 1
int
d61 5
a65 2
	register int ch, cnt, lastch, *p;
	int cflag, dflag, sflag, isstring2;
d81 3
a83 1
			usage();
a87 13
	switch(argc) {
	case 0:
	default:
		usage();
		/* NOTREACHED */
	case 1:
		isstring2 = 0;
		break;
	case 2:
		isstring2 = 1;
		break;
	}

d89 4
a92 3
	 * tr -ds [-c] string1 string2
	 * Delete all characters (or complemented characters) in string1.
	 * Squeeze all characters in string2.
d94 3
a96 12
	if (dflag && sflag) {
		if (!isstring2)
			usage();

		setup(string1, argv[0], &s1, cflag);
		setup(string2, argv[1], &s2, 0);
		
		for (lastch = OOBCH; (ch = getchar()) != EOF;)
			if (!string1[ch] && (!string2[ch] || lastch != ch)) {
				lastch = ch;
				(void)putchar(ch);
			}
d100 8
a107 4
	/*
	 * tr -d [-c] string1
	 * Delete all characters (or complemented characters) in string1.
	 */
d109 12
a120 20
		if (isstring2)
			usage();

		setup(string1, argv[0], &s1, cflag);

		while ((ch = getchar()) != EOF)
			if (!string1[ch])
				(void)putchar(ch);
		exit(0);
	}

	/*
	 * tr -s [-c] string1
	 * Squeeze all characters (or complemented characters) in string1.
	 */
	if (sflag && !isstring2) {
		setup(string1, argv[0], &s1, cflag);

		for (lastch = OOBCH; (ch = getchar()) != EOF;)
			if (!string1[ch] || lastch != ch) {
d122 29
a150 1
				(void)putchar(ch);
a151 28
		exit(0);
	}

	/*
	 * tr [-cs] string1 string2
	 * Replace all characters (or complemented characters) in string1 with
	 * the character in the same position in string2.  If the -s option is
	 * specified, squeeze all the characters in string2.
	 */
	if (!isstring2)
		usage();

	s1.str = argv[0];
	s2.str = argv[1];

	if (cflag)
		for (cnt = NCHARS, p = string1; cnt--;)
			*p++ = OOBCH;

	if (!next(&s2))
		err("empty string2");

	/* If string2 runs out of characters, use the last one specified. */
	if (sflag)
		while (next(&s1)) {
			string1[s1.lastch] = ch = s2.lastch;
			string2[ch] = 1;
			(void)next(&s2);
d153 5
a157 14
	else
		while (next(&s1)) {
			string1[s1.lastch] = ch = s2.lastch;
			(void)next(&s2);
		}

	if (cflag)
		for (cnt = 0, p = string1; cnt < NCHARS; ++p, ++cnt)
			*p = *p == OOBCH ? ch : cnt;

	if (sflag)
		for (lastch = OOBCH; (ch = getchar()) != EOF;) {
			ch = string1[ch];
			if (!string2[ch] || lastch != ch) {
d159 1
a159 1
				(void)putchar(ch);
d161 5
a165 5
		}
	else
		while ((ch = getchar()) != EOF)
			(void)putchar(string1[ch]);
	exit (0);
d168 2
a169 6
static void
setup(string, arg, str, cflag)
	int *string;
	char *arg;
	STR *str;
	int cflag;
d171 1
a171 1
	register int cnt, *p;
d173 35
a207 7
	str->str = arg;
	bzero(string, NCHARS * sizeof(int));
	while (next(str))
		string[str->lastch] = 1;
	if (cflag)
		for (p = string, cnt = NCHARS; cnt--; ++p)
			*p = !*p;
d210 6
a215 2
static void
usage()
d217 1
a217 6
	(void)fprintf(stderr, "usage: tr [-cs] string1 string2\n");
	(void)fprintf(stderr, "       tr [-c] -d string1\n");
	(void)fprintf(stderr, "       tr [-c] -s string1\n");
	(void)fprintf(stderr, "       tr [-c] -ds string1 string2\n");
	exit(1);
}
d219 9
a227 27
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif

void
#if __STDC__
err(const char *fmt, ...)
#else
err(fmt, va_alist)
	char *fmt;
        va_dcl
#endif
{
	va_list ap;
#if __STDC__
	va_start(ap, fmt);
#else
	va_start(ap);
#endif
	(void)fprintf(stderr, "tr: ");
	(void)vfprintf(stderr, fmt, ap);
	va_end(ap);
	(void)fprintf(stderr, "\n");
	exit(1);
	/* NOTREACHED */
@


1.1.1.3
log
@imported from 44lite2
@
text
@d41 1
a41 1
static char sccsid[] = "@@(#)tr.c	8.2 (Berkeley) 5/4/95";
a44 1

a47 2
#include <unistd.h>

@
