#!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # # 7_9.h 7_9_app.c 7_9_apph.c 7_9_clear.c 7_9_cons.c 7_9_dlist.h 7_9_getn.c 7_9_getp.c 7_9_ins.c 7_9_insh.c 7_9_next.c 7_9_prev.c all.c makefile nlink.h tst.c tst.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:11:14 EDT 1990 # echo x - 7_9.h sed 's/^X//' > 7_9.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Exercise 7.9 // A link class from which objects can be derived class dlink { friend class dlist; dlink *next; dlink *prev; public: dlink(dlink *n = 0, dlink *p = 0) { next = n; prev = p; } dlink(dlink &) { next = prev = 0; } void operator=(dlink &) { next = prev = 0; } void insert(dlink *); void append(dlink *); void remove(); ~dlink() { remove(); } friend ostream &operator<<(ostream &out, dlink*n); // DELETE }; // DELETE inline ostream &operator<<(ostream &out, dlink*n) // DELETE { // DELETE out << form("%#x", (long)n) << "\t" << // DELETE form("n: %#x", (long)(n->next)) << "\t" << // DELETE form("p: %#x", (long)(n->prev)); // DELETE return out; // DELETE } // DELETE !EOF! ls -l 7_9.h echo x - 7_9_app.c sed 's/^X//' > 7_9_app.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Append an entry at the end of the list. // This is the same as dlist::insert() except // that dlist::last is adjusted afterwards. void dlist::append(dlink *a) { this->insert(a); last = last->next; } !EOF! ls -l 7_9_app.c echo x - 7_9_apph.c sed 's/^X//' > 7_9_apph.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Append an entry after the // current location of the list. // If curr is not set, append at // the end of the list. void dlist::appendhere(dlink *a) { if (curr) curr->append(a); else this->append(a); } !EOF! ls -l 7_9_apph.c echo x - 7_9_clear.c sed 's/^X//' > 7_9_clear.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // clear the list void dlist::clear() { dlink *l = last; if (!l) return; do { dlink *ll = l; l = l->next; ll->next = ll->prev = 0; } while (l != last); last = 0; } !EOF! ls -l 7_9_clear.c echo x - 7_9_cons.c sed 's/^X//' > 7_9_cons.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ dlist::dlist(dlink *a) { curr = 0; last = a; last->next = last->prev = last; } !EOF! ls -l 7_9_cons.c echo x - 7_9_dlist.h sed 's/^X//' > 7_9_dlist.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // manage a doubly-linked list class dlist { dlink *last; dlink *curr; public: dlist(); dlist(dlink*); ~dlist(); int isempty() { return last != 0; } void clear(); // set current pointer to the ends of the list void reset() { curr = 0; } // move around the list, leaving the links there int next(dlink *&e); int prev(dlink *&e); // move around the list, removing the links int getnext(dlink *&e); int getprev(dlink *&e); // manipulate around the beginning // and end of the list void insert(dlink*); void append(dlink*); // manipulate around the current entry void inserthere(dlink*); void appendhere(dlink*); }; !EOF! ls -l 7_9_dlist.h echo x - 7_9_getn.c sed 's/^X//' > 7_9_getn.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Get the next entry from a list, // removing it afterwards. // curr is left alone. int dlist::getnext(dlink *&a) { if (!last) return 0; // choose the link to remove if (curr) if (curr == last) { curr = 0; return 0; } else a = curr->next; else a = last->next; // remove a from the list if (a == last) last = 0; else a->remove(); return 1; } !EOF! ls -l 7_9_getn.c echo x - 7_9_getp.c sed 's/^X//' > 7_9_getp.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Get the previous entry from a list, // removing it afterwards int dlist::getprev(dlink *&a) { if (!last) return 0; // choose the link to remove if (curr) if (curr == last->prev) { curr = 0; return 0; } else a = curr->prev; else a = curr = last; // remove f from the list if (a == last) last = 0; else a->remove(); return 1; } !EOF! ls -l 7_9_getp.c echo x - 7_9_ins.c sed 's/^X//' > 7_9_ins.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // DELETE #include "nlink.h" // insert an entry at the beginning of the list void dlist::insert(dlink *a) { // DELETE cout << "dlist::insert(" << (char*)(((nlink*)a)->x) << ")\n"; if (last) last->next->insert(a); else { last = a; last->next = last->prev = last; } //DELETE //DELETE cout << "\tlast: " << (nlink*)last; //DELETE cout << "\tfrom last->next\n"; //DELETE for (a = last->next; a != last; a = a->next) //DELETE cout << "\tnext: " << (nlink*)a; } !EOF! ls -l 7_9_ins.c echo x - 7_9_insh.c sed 's/^X//' > 7_9_insh.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Insert an entry before the // current location of the list. // If curr is not set, insert at // the beginning of the list. void dlist::inserthere(dlink *a) { if (curr) curr->insert(a); else this->insert(a); } !EOF! ls -l 7_9_insh.c echo x - 7_9_next.c sed 's/^X//' > 7_9_next.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include // Get the next entry from a list, // moving curr forward. int dlist::next(dlink *&a) { if (!last) return 0; // move curr forward, possibly to // the beginning or end of the list. if (curr) if (curr == last) { curr = 0; return 0; } else curr = curr->next; else curr = last->next; a = curr; return 1; } !EOF! ls -l 7_9_next.c echo x - 7_9_prev.c sed 's/^X//' > 7_9_prev.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Get the previous entry from a list, // moving curr backwards. int dlist::prev(dlink *&a) { if (!last) return 0; // move curr backwards, possibly to // the beginning or end of the list. if (curr) if (curr == last->next) { curr = 0; return 0; } else curr = curr->prev; else curr = last; a = curr; return 1; } !EOF! ls -l 7_9_prev.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 #include "7_9.h" #include "nlink.h" #include "7_9_dlist.h" #include "7_6e.c" /* dlink::remove() */ #include "7_9_app.c" /* dlist::append() */ #include "7_6_cons1.c" /* dlist() */ #include "7_6_dest.c" /* ~dlist() */ #include "7_6c.c" /* dlink::insert() */ #include "7_6d.c" /* dlink::append() */ #include "7_9_apph.c" #include "7_9_clear.c" #include "7_9_cons.c" #include "7_9_getn.c" #include "7_9_getp.c" #include "7_9_ins.c" #include "7_9_insh.c" #include "7_9_next.c" #include "7_9_prev.c" !EOF! ls -l all.c echo x - makefile sed 's/^X//' > makefile << '!EOF!' CC= CC -I. -I../7.6dir -I../../CC CFLAGS= all: tst tst: tst.o all.o $(CC) -o tst tst.o all.o tst.o: tst.c 7_9.h 7_9_dlist.h nlink.h $(CC) -c tst.c all.o: all.c 7_9.h 7_9_dlist.h nlink.h \ 7_9_apph.c 7_9_clear.c 7_9_cons.c 7_9_getn.c 7_9_getp.c \ 7_9_ins.c 7_9_insh.c 7_9_next.c 7_9_prev.c 7_9_app.c $(CC) -c all.c CMP= tst.cmp OUT= tst.out tst.out: tst ; tst > tst.out test: all $(CMP) $(OUT) cmp tst.out tst.cmp @echo test done !EOF! ls -l makefile echo x - nlink.h sed 's/^X//' > nlink.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #ifndef NLINK_H #define NLINK_H class nlink : public dlink { public: void *x; nlink(char*nx) { x = nx; } }; inline ostream &operator<<(ostream &out, nlink*n) { out << (dlink*)n << "\t" << (char*)(n->x) << "\n"; return out; } #endif !EOF! ls -l nlink.h echo x - tst.c sed 's/^X//' > tst.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include "7_9.h" #include "nlink.h" #include "7_9_dlist.h" main() { dlist xdlist; /* nlink i1("ins 1"); xdlist.insert(&i1); nlink a1("app 1"); xdlist.append(&a1); nlink i2("ins 2"); xdlist.insert(&i2); nlink a2("app 2"); xdlist.append(&a2); */ nlink hello("hello"); xdlist.insert(&hello); nlink there("there"); xdlist.insert(&there); nlink how("how"); xdlist.insert(&how); nlink are("are"); xdlist.insert(&are); nlink you("you"); xdlist.append(&you); nlink today("today"); xdlist.insert(&today); nlink *x; cout << "forwards\n"; while (xdlist.next(x)) cout << "'" << (char*)x->x << "'\n"; cout << "\nbackwards\n"; while (xdlist.prev(x)) cout << "'" << (char*)x->x << "'\n"; xdlist.next(x); xdlist.next(x); nlink Beep("Beep"); xdlist.inserthere(&Beep); nlink Boop("Boop"); xdlist.appendhere(&Boop); xdlist.reset(); cout << "\nforwards, removing\n"; while (xdlist.getnext(x)) cout << "'" << (char*)x->x << "'\n"; cout << "\nbackwards\n"; while (xdlist.getprev(x)) cout << "'" << (char*)x->x << "'\n"; return 0; } !EOF! ls -l tst.c echo x - tst.cmp sed 's/^X//' > tst.cmp << '!EOF!' forwards 'today' 'are' 'how' 'there' 'hello' 'you' backwards 'you' 'hello' 'there' 'how' 'are' 'today' forwards, removing 'today' 'Beep' 'are' 'Boop' 'how' 'there' 'hello' 'you' backwards !EOF! ls -l tst.cmp # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0