#!/bin/sh
# This is a shar archive.
# The rest of this file is a shell script which will extract:
#
# 8_12a.h 8_12a1.c 8_12a2.c 8_12a3.c 8_12a4.c 8_12a5.c 8_12b.h 8_12b1.h 8_12b2.h 8_12b3.h 8_12b4.h 8_12b5.c all.c makefile memmove.c pat.h pat.input pat3.input pat4.input tst12.c tst12.cmp tst3.c tst3.cmp tst4.c tst4.cmp
#
# To extract the files from this shell archive file simply
# create a directory for this file, move the archive file
# to it and enter the command
#
#	sh filename
# 
# The files will be extracted automatically.
# Note: Do not use csh.
#
# Archive created: Mon Jul 30 23:12:12 EDT 1990
#
echo x - 8_12a.h
sed 's/^X//' > 8_12a.h << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// A streambuf with a
// bit extra thrown in.
struct extrabuf : public streambuf
{
    istream *in;
    char dobuffering;

    extrabuf(istream &inp) { in = &inp; dobuffering = 0; }
    ~extrabuf() { }

    int overflow(int);
    int underflow();
    int reallocate();
    void setbuffering();
    void resetbuffering();
};
!EOF!
ls -l 8_12a.h
echo x - 8_12a1.c
sed 's/^X//' > 8_12a1.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// manage running out of space within the buffer
int extrabuf::overflow(int c)
{
//cerr << "overflow(" << chr(c) << ") invoked, alloc=" << alloc << "\n"; // DELETE
    if ((alloc ? reallocate() : allocate()) == EOF)
	{					// DELETE
//cerr << "\treturning -1\n";			// DELETE
	return EOF;
	}					// DELETE

    if (c != EOF)
	*pptr++ = c;

//cerr << "\treturning " << chr(c) << "\n";	// DELETE
    return c & UCHAR_MAX;
}
!EOF!
ls -l 8_12a1.c
echo x - 8_12a2.c
sed 's/^X//' > 8_12a2.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// manage running out of characters within the buffer
int extrabuf::underflow()
{
//cerr << "underflow() invoked, dobuffering=" << dobuffering << "\n"; // DELETE
//cerr << "\tbase=" << form("%#x", base) << "\n";	// DELETE
//cerr << "\tgptr=" << form("%#x", gptr) << "\n";	// DELETE
//cerr << "\tpptr=" << form("%#x", pptr) << "\n";	// DELETE
//cerr << "\teptr=" << form("%#x", eptr) << "\n";	// DELETE
    char c;
    if (in->get(c))
	{
// cerr << "\treturning c=" << chr(c) << "\n";	// DELETE
	sputc(c);
	if (!dobuffering)
	    stossc();

//cerr << "\t----------------\n";	// DELETE
//cerr << "\tbase=" << form("%#x", base) << "\n";	// DELETE
//cerr << "\tgptr=" << form("%#x", gptr) << "\n";	// DELETE
//cerr << "\tpptr=" << form("%#x", pptr) << "\n";	// DELETE
//cerr << "\teptr=" << form("%#x", eptr) << "\n";	// DELETE
//cerr << "\treturning " << chr(c) << "\n";	// DELETE
	return c & UCHAR_MAX;
	}

    else
	{					// DELETE
//cerr << "\treturning -1\n";			// DELETE
	return EOF;
	}					// DELETE
}
!EOF!
ls -l 8_12a2.c
echo x - 8_12a3.c
sed 's/^X//' > 8_12a3.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// reallocate the internal streambuf buffer
int extrabuf::reallocate()
{
//cerr << "reallocate() invoked, dobuffering=" << dobuffering << "\n"; // DELETE
//cerr << "\tbase=" << form("%#x", base) << "\n";	// DELETE
//cerr << "\tgptr=" << form("%#x", gptr) << "\n";	// DELETE
//cerr << "\tpptr=" << form("%#x", pptr) << "\n";	// DELETE
//cerr << "\teptr=" << form("%#x", eptr) << "\n";	// DELETE
    // the buffer is full
    if ((gptr == base) || dobuffering)
	{
	int curlength = eptr - base;
	int newlength = curlength + BUFSIZ;
	char *obase = base;

	base = new char[newlength];
	if (base != NULL)
	    {
	    gptr = base + (gptr - obase);
	    pptr = base + (pptr - obase);
	    eptr = base + newlength;
	    memcpy(base, obase, curlength);
	    delete obase;
//cerr << "\t----------------\n";	// DELETE
//cerr << "\tbase=" << form("%#x", base) << "\n";	// DELETE
//cerr << "\tgptr=" << form("%#x", gptr) << "\n";	// DELETE
//cerr << "\tpptr=" << form("%#x", pptr) << "\n";	// DELETE
//cerr << "\teptr=" << form("%#x", eptr) << "\n";	// DELETE
//cerr << "\treturning 0\n";			// DELETE
	    return 0;
	    }

	// the allocation failed
	else
	    {
	    base = obase;
//cerr << "\treturning -1\n";			// DELETE
	    return EOF;
	    }
	}

    // there's some room at the beginning of the buffer
    else
	{
	int length = pptr - gptr;
	if (length > 0)
	    memmove(base, gptr, length);
	gptr = base;
	pptr = base + length;
//cerr << "\t----------------\n";	// DELETE
//cerr << "\tbase=" << form("%#x", base) << "\n";	// DELETE
//cerr << "\tgptr=" << form("%#x", gptr) << "\n";	// DELETE
//cerr << "\tpptr=" << form("%#x", pptr) << "\n";	// DELETE
//cerr << "\teptr=" << form("%#x", eptr) << "\n";	// DELETE
//cerr << "\treturning 0\n";			// DELETE
	return 0;
	}
}
!EOF!
ls -l 8_12a3.c
echo x - 8_12a4.c
sed 's/^X//' > 8_12a4.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// Reset get pointer to point to the
// beginning of the buffer. Set the state
// flag to indicate that get() calls
// need to be buffered.
void extrabuf::setbuffering()
{
// cerr << "setbuffering() invoked\n";	// DELETE
// cerr << "\tgptr=" << form("%#x", gptr) << "\n";
// cerr << "\tbase=" << form("%#x", base) << "\n";
    dobuffering = 1;
    if (gptr != base)
	{
	int length = pptr - gptr;
	if (length > 0)
	    memmove(base, gptr, length);
	gptr = base;
	pptr = base + length;
	}
}
!EOF!
ls -l 8_12a4.c
echo x - 8_12a5.c
sed 's/^X//' > 8_12a5.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// Reset the state flag to indicate that get() calls
// need not be buffered. Make sure that new get()
// calls start over at the base.
void extrabuf::resetbuffering()
{
// cerr << "resetbuffering() invoked\n";	// DELETE
    dobuffering = 0;
    gptr = base;
}
!EOF!
ls -l 8_12a5.c
echo x - 8_12b.h
sed 's/^X//' > 8_12b.h << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include "8_12b1.h"	/* EXPAND */

#include "8_12b2.h"	/* EXPAND4 */

#include "8_12b3.h"	/* EXPAND4 */

#include "8_12b4.h"	/* EXPAND4 */
};
!EOF!
ls -l 8_12b.h
echo x - 8_12b1.h
sed 's/^X//' > 8_12b1.h << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// An istream with an additional
// pattern checking function
class pat : public istream
{
    extrabuf *ebp;
    int existingstream;

public:
    // bind to an existing input stream
    pat(istream& in) :
	ebp(new extrabuf(in))
    { existingstream = 1; }
!EOF!
ls -l 8_12b1.h
echo x - 8_12b2.h
sed 's/^X//' > 8_12b2.h << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// bind to file
pat(int fd, int sk = 1, ostream* t = 0) : 
    ebp(new extrabuf(*new istream(fd, sk, t)))
{ existingstream = 0; }

// bind to string
pat(int size, char *p, int sk = 1) : 
    ebp(new extrabuf(*new istream(size, p, sk)))
{ existingstream = 0; }

// bind to buffer
pat(streambuf *s, int sk = 1, ostream* t = 0) :
    ebp(new extrabuf(*new istream(s, sk, t)))
{ existingstream = 0; }
!EOF!
ls -l 8_12b2.h
echo x - 8_12b3.h
sed 's/^X//' > 8_12b3.h << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
X~pat()
{
    if (!existingstream)
	delete ebp->in;
    delete ebp;
}
!EOF!
ls -l 8_12b3.h
echo x - 8_12b4.h
sed 's/^X//' > 8_12b4.h << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
int match(char*);
!EOF!
ls -l 8_12b4.h
echo x - 8_12b5.c
sed 's/^X//' > 8_12b5.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// match a pattern on the input stream
// %d looks for an integer & stops at the first
//	non-integer character
// %f looks for a floating point number & stops ...
// %c matches a single character
// %s matches a white-space delineated string
// %% matches %
// ' ' matches any white space
// 'X' matches the character X

int pat::match(char *pattern)
{
    // reset base ptr to pt to beginning of buffer
    ebp->setbuffering();

    // loop through the pattern looking
    // for things to match.
    int goodpattern = 1;
    while (*pattern && goodpattern)
	{
	int c = ebp->sgetc();
	char p = *pattern++;

// define a couple of small macros for
// some common sequences
#define Next()				\
    ebp->stossc(), c = ebp->sgetc()

#define doloop(testfunc)		\
    do { Next(); } while (testfunc(c))

	switch (p)
	    {
	    // space matches arbitrary white space
	    case ' ':
		if (isspace(c))
		    doloop(isspace);

		else
		    goodpattern = 0;
		break;

	    // a pattern: %d, %f, %c, %s, %%
	    case '%':
		p = *pattern++;

		// check for patterns which
		// toss white space first
		if ((p == 'd') || (p == 'f') ||
		    (p == 's'))
		    if (isspace(c))
			doloop(isspace);

		// now skip past the particular type
		switch (p)
		    {
		    // decimal number
		    case 'd':
			if ((c == '-') || (c == '+'))
			    Next();

			if (isdigit(c))
			    doloop(isdigit);

			else
			    goodpattern = 0;
			break;

		    // floating point
		    case 'f':
			if ((c == '-') || (c == '+'))
			    Next();

			int digitsbefore = 0;
			int hasdecimal = 0;
			int digitsafter = 0;
			int hasexponent = 0;

			if (isdigit(c))
			    {
			    digitsbefore = 1;
			    doloop(isdigit);
			    }

			if (c == '.')
			    {
			    hasdecimal = 1;
			    Next();

			    if (isdigit(c))
				{
				digitsafter = 1;
				doloop(isdigit);
				}
			    }

			if ((c == 'e') || (c == 'E'))
			    {
			    hasexponent = 1;
			    Next();

			    if ((c == '-') || (c == '+'))
				Next();

			    if (isdigit(c))
				doloop(isdigit);

			    else
				goodpattern = 0;
			    }

			if (!((digitsbefore &&
			       (hasdecimal ||
				hasexponent)) ||
			      digitsafter))
			    goodpattern = 0;

			break;

		    // any string. leading white
		    // space was tossed above
		    case 's':
			doloop(!isspace);
			break;

		    // any single character
		    case 'c':
			ebp->stossc();
			break;

		    // match single %
		    case '%':
			if (ebp->sgetc() == '%')
			    ebp->stossc();

			else
			    goodpattern = 0;
			break;

		    // unknown pattern
		    default:
			goodpattern = 0;
			break;
		    }
		break;

	    // non-pattern, match the character
	    default:
		if (c == p)
		    ebp->stossc();

		else
		    goodpattern = 0;
		break;
	    }
	}

    ebp->resetbuffering();
    return goodpattern;
}
!EOF!
ls -l 8_12b5.c
echo x - all.c
sed 's/^X//' > all.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <pat.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include "8_12a1.c"	/* int extrabuf::overflow(int) */
#include "8_12a2.c"	/* int extrabuf::underflow() */
#include "8_12a3.c"	/* int extrabuf::reallocate() */
#include "8_12a4.c"	/* void extrabuf::setbuffering() */
#include "8_12a5.c"	/* void extrabuf::resetbuffering() */
#include "8_12b5.c"	/* int pat::match(char*) */
!EOF!
ls -l all.c
echo x - makefile
sed 's/^X//' > makefile << '!EOF!'
CC= CC -I. -I../../CC
CFLAGS=

all: tst12 tst3 tst4

tst12: tst12.o all.o memmove.o
	$(CC) tst12.o all.o -o tst12 memmove.o

tst3: tst3.o all.o memmove.o
	$(CC) tst3.o all.o -o tst3 memmove.o

tst4: tst4.o all.o memmove.o
	$(CC) tst4.o all.o -o tst4 memmove.o

memmove.o: memmove.c
	$(CC) -c memmove.c

all.o: all.c pat.h 8_12a.h 8_12a1.c 8_12a2.c 8_12a3.c 8_12a4.c 8_12a5.c 8_12b.h 8_12b1.h 8_12b2.h 8_12b3.h 8_12b4.h 8_12b5.c
	$(CC) $(CFLAGS) -c all.c

tst12.o: tst12.c 8_12a.h 8_12b.h 8_12b1.h 8_12b2.h 8_12b3.h 8_12b4.h pat.h
	$(CC) $(CFLAGS) -c tst12.c

tst3.o: tst3.c 8_12a.h 8_12b.h 8_12b1.h 8_12b2.h 8_12b3.h 8_12b4.h pat.h
	$(CC) $(CFLAGS) -c tst3.c

tst4.o: tst4.c 8_12a.h 8_12b.h 8_12b1.h 8_12b2.h 8_12b3.h 8_12b4.h pat.h
	$(CC) $(CFLAGS) -c tst4.c

OUT= tst12.out tst3.out tst4.out
CMP= tst12.cmp tst3.cmp tst4.cmp

tst12.out: tst12 ;	tst12 < pat.input > tst12.out
tst3.out: tst3 ;	tst3 < pat3.input > tst3.out
tst4.out: tst4 ;	tst4 < pat4.input > tst4.out

test: all $(OUT) $(CMP)
	cat pat.input
	cmp tst12.out tst12.cmp
	cmp tst3.out tst3.cmp
	cmp tst4.out tst4.cmp
	@echo test done
!EOF!
ls -l makefile
echo x - memmove.c
sed 's/^X//' > memmove.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
char *memmove(char *dst, register char *src, register int n) {
    if ((dst > src) && (dst < src + n)) {
	src += n;
	for (register char *svdst = dst + n; n-- > 0; )
	    *--svdst = *--src;
    } else {
	for (register char *svdst = dst; n-- > 0; )
	    *svdst++ = *src++;
    }
    return dst;
}
!EOF!
ls -l memmove.c
echo x - pat.h
sed 's/^X//' > pat.h << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <stream.h>
#include "8_12a.h"	/* class extrabuf */
#include "8_12b.h"	/* class pat */
!EOF!
ls -l pat.h
echo x - pat.input
sed 's/^X//' > pat.input << '!EOF!'
1.75 75 5
123 4213 12341 2332
!EOF!
ls -l pat.input
echo x - pat3.input
sed 's/^X//' > pat3.input << '!EOF!'
1.75 75 5. 123 4213 12341 2332
!EOF!
ls -l pat3.input
echo x - pat4.input
sed 's/^X//' > pat4.input << '!EOF!'
1.75 75 5. 123 4213 12341 2332
root::0:root
other::1:
bin::2:root,bin,daemon
sys::3:root,bin,sys,adm
adm::4:root,adm,daemon
uucp::5:root,uucp
mail::6:root
daemon::12:root,daemon
docx::21:pcor,russak,mds,dsl,jeremy,bwp,hansen,coleman,chu,jack
guest::22:
cmts::23:cmts,hansen,mzal
mesa::24:mesa,hansen,mzal
mrstat::26:cmts,hansen,mzal,bwp,danb,guidi,linda,dsl,eby,cbp,hlb,pcor,russak,clt,mds,aku,wpw,jack,cjs,bcc,paul,alf,sld,drr,jim,larry,jmt
intest::27:
arch::29:efh,maryrose,danb,russak,linda
ots::31:butterly,fwl,daved,so,dwr,shorty,mjk,mjm,aj
dbx::35:
erm::37:efs,caf,jaa,mjb,lth,rlm
games::50:hansen,autilio,avi
news::51:netnews
slan::57:slan,root
sie::80:
sable::117:sable
dptg::88:emm,kbs,jak,ecc,jhc,jrw,rkh
DOS-ash::92:msnet
DOS--sh::93:msnet
DOS-a-h::94:msnet
DOS-as-::95:msnet
DOS---h::96:msnet
DOS--s-::97:msnet
DOS-a--::98:msnet
DOS----::99:msnet
exptools::90:exptools
vm::100:vmsys
pcor::102:pcor,russak,eth,jim,hansen,jack
dx::880:
OLD::1000:scy
olympus::1100:olympus,aku
tsys::1101:root,tadm
root::0:root
other::1:
bin::2:root,bin,daemon
sys::3:root,bin,sys,adm
adm::4:root,adm,daemon
uucp::5:root,uucp
mail::6:root
daemon::12:root,daemon
docx::21:pcor,russak,mds,dsl,jeremy,bwp,hansen,coleman,chu,jack
guest::22:
cmts::23:cmts,hansen,mzal
mesa::24:mesa,hansen,mzal
mrstat::26:cmts,hansen,mzal,bwp,danb,guidi,linda,dsl,eby,cbp,hlb,pcor,russak,clt,mds,aku,wpw,jack,cjs,bcc,paul,alf,sld,drr,jim,larry,jmt
intest::27:
arch::29:efh,maryrose,danb,russak,linda
ots::31:butterly,fwl,daved,so,dwr,shorty,mjk,mjm,aj
dbx::35:
erm::37:efs,caf,jaa,mjb,lth,rlm
games::50:hansen,autilio,avi
news::51:netnews
slan::57:slan,root
sie::80:
sable::117:sable
dptg::88:emm,kbs,jak,ecc,jhc,jrw,rkh
DOS-ash::92:msnet
DOS--sh::93:msnet
DOS-a-h::94:msnet
DOS-as-::95:msnet
DOS---h::96:msnet
DOS--s-::97:msnet
DOS-a--::98:msnet
DOS----::99:msnet
exptools::90:exptools
vm::100:vmsys
pcor::102:pcor,russak,eth,jim,hansen,jack
dx::880:
OLD::1000:scy
olympus::1100:olympus,aku
tsys::1101:root,tadm
!EOF!
ls -l pat4.input
echo x - tst12.c
sed 's/^X//' > tst12.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <pat.h>

main()
{
    pat p(cin);
    int x, y;
    float f;

    if (p.match("%d %f %d")) {
	cout << "match 1 %d %f %d succeeded\n";
	p >> x >> f >> y;
    } else if (p.match("%f %d %d")) {
	cout << "match 2 %f %d %d succeeded\n";
	p >> f >> x >> y;
    } else {
	cout << "default succeeded\n";
	p >> x >> y >> f;
    }

    cout << "x = " << x << "\n"
	 << "y = " << y << "\n"
	 << "f = " << f << "\n";

    int a = -1, b = -2;
    p >> a >> b;
    cout << "a = " << a << "\n"
	 << "b = " << b << "\n";
    return 0;
}
!EOF!
ls -l tst12.c
echo x - tst12.cmp
sed 's/^X//' > tst12.cmp << '!EOF!'
match 2 %f %d %d succeeded
x = 75
y = 5
f = 1.75
a = 123
b = 4213
!EOF!
ls -l tst12.cmp
echo x - tst3.c
sed 's/^X//' > tst3.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <pat.h>

main()
{
    pat p(cin);
    int x;
    float f;

    if (p.match("%f %d"))
	cout << "match %f %d succeeded\n";
    else
	cout << "match %f %d failed\n";
    p >> f;
    cout << "f=" << f << "\n";
    if (p.match("%d %f"))
	cout << "match %d %f succeeded\n";
    else
	cout << "match %d %f failed\n";
    p >> x;
    cout << "x=" << x << "\n";
    p >> f;
    cout << "f=" << f << "\n";
    p >> x;
    cout << "x=" << x << "\n";
    return 0;
}
!EOF!
ls -l tst3.c
echo x - tst3.cmp
sed 's/^X//' > tst3.cmp << '!EOF!'
match %f %d succeeded
f=1.75
match %d %f succeeded
x=75
f=5
x=123
!EOF!
ls -l tst3.cmp
echo x - tst4.c
sed 's/^X//' > tst4.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <pat.h>

main()
{
    pat p(cin);
    int x;
    float f;

    if (p.match("%f %d"))
	cout << "match %f %d succeeded\n";
    else
	cout << "match %f %d failed\n";
    p >> f;
    cout << "f=" << f << "\n";
    if (p.match("%d %f"))
	cout << "match %d %f succeeded\n";
    else
	cout << "match %d %f failed\n";
    p >> x;
    cout << "x=" << x << "\n";
    p >> f;
    cout << "f=" << f << "\n";
    p >> x;
    cout << "x=" << x << "\n";

    char c[512];
    for (;;)
	{
	p >> c;
	if (!p.good())
	    break;
	cout << c << "\n";
	}

    return 0;
}
!EOF!
ls -l tst4.c
echo x - tst4.cmp
sed 's/^X//' > tst4.cmp << '!EOF!'
match %f %d succeeded
f=1.75
match %d %f succeeded
x=75
f=5
x=123
4213
12341
2332
root::0:root
other::1:
bin::2:root,bin,daemon
sys::3:root,bin,sys,adm
adm::4:root,adm,daemon
uucp::5:root,uucp
mail::6:root
daemon::12:root,daemon
docx::21:pcor,russak,mds,dsl,jeremy,bwp,hansen,coleman,chu,jack
guest::22:
cmts::23:cmts,hansen,mzal
mesa::24:mesa,hansen,mzal
mrstat::26:cmts,hansen,mzal,bwp,danb,guidi,linda,dsl,eby,cbp,hlb,pcor,russak,clt,mds,aku,wpw,jack,cjs,bcc,paul,alf,sld,drr,jim,larry,jmt
intest::27:
arch::29:efh,maryrose,danb,russak,linda
ots::31:butterly,fwl,daved,so,dwr,shorty,mjk,mjm,aj
dbx::35:
erm::37:efs,caf,jaa,mjb,lth,rlm
games::50:hansen,autilio,avi
news::51:netnews
slan::57:slan,root
sie::80:
sable::117:sable
dptg::88:emm,kbs,jak,ecc,jhc,jrw,rkh
DOS-ash::92:msnet
DOS--sh::93:msnet
DOS-a-h::94:msnet
DOS-as-::95:msnet
DOS---h::96:msnet
DOS--s-::97:msnet
DOS-a--::98:msnet
DOS----::99:msnet
exptools::90:exptools
vm::100:vmsys
pcor::102:pcor,russak,eth,jim,hansen,jack
dx::880:
OLD::1000:scy
olympus::1100:olympus,aku
tsys::1101:root,tadm
root::0:root
other::1:
bin::2:root,bin,daemon
sys::3:root,bin,sys,adm
adm::4:root,adm,daemon
uucp::5:root,uucp
mail::6:root
daemon::12:root,daemon
docx::21:pcor,russak,mds,dsl,jeremy,bwp,hansen,coleman,chu,jack
guest::22:
cmts::23:cmts,hansen,mzal
mesa::24:mesa,hansen,mzal
mrstat::26:cmts,hansen,mzal,bwp,danb,guidi,linda,dsl,eby,cbp,hlb,pcor,russak,clt,mds,aku,wpw,jack,cjs,bcc,paul,alf,sld,drr,jim,larry,jmt
intest::27:
arch::29:efh,maryrose,danb,russak,linda
ots::31:butterly,fwl,daved,so,dwr,shorty,mjk,mjm,aj
dbx::35:
erm::37:efs,caf,jaa,mjb,lth,rlm
games::50:hansen,autilio,avi
news::51:netnews
slan::57:slan,root
sie::80:
sable::117:sable
dptg::88:emm,kbs,jak,ecc,jhc,jrw,rkh
DOS-ash::92:msnet
DOS--sh::93:msnet
DOS-a-h::94:msnet
DOS-as-::95:msnet
DOS---h::96:msnet
DOS--s-::97:msnet
DOS-a--::98:msnet
DOS----::99:msnet
exptools::90:exptools
vm::100:vmsys
pcor::102:pcor,russak,eth,jim,hansen,jack
dx::880:
OLD::1000:scy
olympus::1100:olympus,aku
tsys::1101:root,tadm
!EOF!
ls -l tst4.cmp
# The following exit is to ensure that extra garbage 
# after the end of the shar file will be ignored.
exit 0
