#!/bin/sh
# This is a shar archive.
# The rest of this file is a shell script which will extract:
#
# 6_14a.c 6_14b.c 6_14c.c 6_14d1.c 6_14d2.c makefile tsta.c tsta.cmp tstb.c tstb.cmp tstc.c tstc.cmp tstc.in
#
# 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:06:15 EDT 1990
#
echo x - 6_14a.c
sed 's/^X//' > 6_14a.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// class complex from section 6.3.1
// rewritten to use member definitions
class complex
{
    double re, im;
public:
    complex(double r, double i = 0) { re=r; im=i; }
    
    complex operator+(complex j);
    complex operator-(complex j);
    complex operator-();
    complex operator*(complex j);
    friend ostream &operator<<(ostream &out, complex j);				// DELETE
};
!EOF!
ls -l 6_14a.c
echo x - 6_14b.c
sed 's/^X//' > 6_14b.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// class tiny from section 6.3.2
// rewritten to use member definitions
class tiny
{
    char v;

    int assign(int i)
    {
	return v = (i&~63) ?
	    (error("range error"),0) :
	    i;
    }

public:
    tiny(int i)		  { assign(i); }
    tiny(tiny& t)	  { v = t.v; }
    int operator=(tiny&t) { return v = t.v; }
    int operator=(int i)  { return assign(i); }
    operator int()	  { return v; }
};
!EOF!
ls -l 6_14b.c
echo x - 6_14c.c
sed 's/^X//' > 6_14c.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
// class string from section 6.9
// rewritten to use member definitions
class string
{
    struct srep
    {
	char *s;	// pointer to data
	int n;		// reference count
    };
    srep *p;

public:
    string(char *);	// string x = "abc"
    string();		// string x;
    string(string &);	// string x = string ...
    string& operator=(char *);
    string& operator=(string &);
    ~string();
    char& operator[](int i);

    friend ostream& operator<<(ostream&, string&);
    friend istream& operator>>(istream&, string&);

    int operator==(char *s)
	{ return strcmp(p->s, s) == 0; }

    int operator==(string &y)
	{ return strcmp(p->s, y.p->s) == 0; }

    int operator!=(char *s)
	{ return strcmp(p->s, s) != 0; }

    int operator!=(string &y)
	{ return strcmp(p->s, y.p->s) != 0; }
};
!EOF!
ls -l 6_14c.c
echo x - 6_14d1.c
sed 's/^X//' > 6_14d1.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
complex i, j;
i = 3 + j;
!EOF!
ls -l 6_14d1.c
echo x - 6_14d2.c
sed 's/^X//' > 6_14d2.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
string s = "abc";
int i = "def" == s;
!EOF!
ls -l 6_14d2.c
echo x - makefile
sed 's/^X//' > makefile << '!EOF!'
CC= CC -I. -I../../CC
CFLAGS=	-I.
ERROR= ../../error.a

all: tsta tstb tstc

tsta: tsta.c 6_14a.c
	$(CC) $(CFLAGS) tsta.c -o tsta

tstb: tstb.c 6_14b.c
	$(CC) $(CFLAGS) tstb.c -o tstb

tstc: tstc.c 6_14c.c
	$(CC) $(CFLAGS) tstc.c -o tstc $(ERROR)

CMP= tsta.cmp tstb.cmp tstc.cmp
OUT= tsta.out tstb.out tstc.out

tsta.out: tsta ;		tsta > tsta.out
tstb.out: tstb ;		tstb > tstb.out
tstc.out: tstc tstc.in ;	tstc < tstc.in > tstc.out

test: all $(OUT) $(CMP)
	cmp tsta.out tsta.cmp
	cmp tstb.out tstb.cmp
	cmp tstc.out tstc.cmp
	echo tests done
!EOF!
ls -l makefile
echo x - tsta.c
sed 's/^X//' > tsta.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <stream.h>
#include "6_14a.c"

ostream &operator<<(ostream &out, complex j)
{ return out << "(" << j.re << ", " << j.im << ")"; }
inline complex complex::operator+(complex j) { complex x(re+j.re, im+j.im); return x; }
inline complex complex::operator-(complex j) { complex x(re-j.re, im-j.im); return x; }
inline complex complex::operator-() { complex x(-re, -im); return x; }
inline complex complex::operator*(complex j) { complex x(re*j.re, im*j.im); return x; }

main()
{
    complex i = 0.0, j = 1.0;
    cout << "i= " << i << ", j=" << j << "\n";
    i = j + 3.0;
    cout << "i= " << i << ", j=" << j << "\n";
    i = j - 3.0;
    cout << "i= " << i << ", j=" << j << "\n";
    i = -j;
    cout << "i= " << i << ", j=" << j << "\n";
    i = i * j;
    cout << "i= " << i << ", j=" << j << "\n";
    return 0;
}
!EOF!
ls -l tsta.c
echo x - tsta.cmp
sed 's/^X//' > tsta.cmp << '!EOF!'
i= (0, 0), j=(1, 0)
i= (4, 0), j=(1, 0)
i= (-2, 0), j=(1, 0)
i= (-1, 0), j=(1, 0)
i= (-1, 0), j=(1, 0)
!EOF!
ls -l tsta.cmp
echo x - tstb.c
sed 's/^X//' > tstb.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <stream.h>
void error(char *fmt)
{
    cout << fmt << "\n";
}
#include "6_14b.c"

main()
{
    tiny c1 = 2;
    cout << "c1 = " << int(c1) << "\n";
    tiny c2 = 62;
    cout << "c2 = " << int(c2) << "\n";
    tiny c3 = c2 - c1;
    cout << "c3 = " << int(c3) << "\n";
    tiny c4 = c3;
    cout << "c4 = " << int(c4) << "\n";
    int i = c1 + c2;
    cout << "i = " << int(i) << "\n";
    c1 = c2 + 2 * c1;
    cout << "c1 = " << int(c1) << "\n";
    c2 = c1 - i;
    cout << "c2 = " << int(c2) << "\n";
    c3 = c2;
    cout << "c3 = " << int(c3) << "\n";
    return 0;
}
!EOF!
ls -l tstb.c
echo x - tstb.cmp
sed 's/^X//' > tstb.cmp << '!EOF!'
c1 = 2
c2 = 62
c3 = 60
c4 = 60
i = 64
range error
c1 = 0
range error
c2 = 0
c3 = 0
!EOF!
ls -l tstb.cmp
echo x - tstc.c
sed 's/^X//' > tstc.c << '!EOF!'
/* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
/* The C++ Answer Book */
/* Tony Hansen */
/* All rights reserved. */
#include <stream.h>
#include <error.h>
#include <string.h>
#include "6_14c.c"

string::string()
{
    p = new srep;
    p->s = 0;
    p->n = 1;
}

string::string(char* s)
{
    p = new srep;
    p->s = new char[ strlen(s) + 1 ];
    strcpy(p->s, s);
    p->n = 1;
}

string::string(string &x)
{
    x.p->n++;
    p = x.p;
}

string::~string()
{
    if (--p->n == 0) {
	delete p->s;
	delete p;
    }
}

string &string::operator=(char *s)
{
    if (p->n > 1) {
	p->n--;
	p = new srep;
    } else if (p->n == 1)
	delete p->s;

    p->s = new char[strlen(s) + 1];
    strcpy(p->s, s);
    p->n = 1;
    return *this;
}

string &string::operator=(string &x)
{
    x.p->n++;
    if (--p->n == 0) {
	delete p->s;
	delete p;
    }
    p = x.p;
    return *this;
}

ostream &operator<<(ostream &out, string &x)
{
    return out << x.p->s << " [" << x.p->n << "]\n";
}

istream &operator>>(istream &s, string &x)
{
    char buf[256];
    s >> buf;
    x = buf;
    cout << "echo: " << x << "\n";
    return s;
}

main()
{
    string s = "abc";
    cout << "s = " << s << "\n";
    int i = s == "def";
    cout << "i = " << i << "\n";

    string x[100];
    int n;
    cout << "here we go\n";
    for (n = 0; cin >> x[n]; n++) {
	string y;
	if (n == 100) error("too many strings");
	cout << (y = x[n]);
	if (y=="done") break;
    }
    cout << "here we go back again\n";
    for (i = n-1; 0<=i; i--)
	cout << x[i];
    return 0;
}
!EOF!
ls -l tstc.c
echo x - tstc.cmp
sed 's/^X//' > tstc.cmp << '!EOF!'
s = abc [1]

i = 0
here we go
echo: hello [1]

hello [2]
echo: there [1]

there [2]
echo: this [1]

this [2]
echo: is [1]

is [2]
echo: a [1]

a [2]
echo: test [1]

test [2]
echo: of [1]

of [2]
echo: done [1]

done [2]
here we go back again
of [1]
test [1]
a [1]
is [1]
this [1]
there [1]
hello [1]
!EOF!
ls -l tstc.cmp
echo x - tstc.in
sed 's/^X//' > tstc.in << '!EOF!'
hello
there
this is
a test
of
done
!EOF!
ls -l tstc.in
# The following exit is to ensure that extra garbage 
# after the end of the shar file will be ignored.
exit 0