home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_10_09
/
schum2.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-24
|
7KB
|
346 lines
/*
Listing 2
outlist.cpp--Print out a "calling tree."
Compiler: Borland C++ 2.0.
Library: SoftC version 2.1f or 3.0.
17 March 1992, by Mark W. Schumann
Usenet: mark@whizbang.ncoast.org
Compile (Borland) with:
bcc -ms -lm outlist.cpp scdbp20s.lib
This program uses a C++ string class originally
developed by John Bernstein (CIS 70244,1237).
You can probably substitute any of the usual
C++ implementations of strings without too
much trouble.
-------------------------------------------------
OUTLIST-- Print out a "calling tree."
Copyright (C) 1992 by Mark W. Schumann
This program is distributed in the hope that
it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
*/
#include <softc.h>
#include <sc_base.h>
#include <ctype.h>
#include <dir.h>
#include <iostream.h>
#include <string.h>
#include "oostring.h" // Bernstein's class header.
int dbf = -1; // Handle of CALLTREE.DBF.
int ntx1 = -1; // ...of MEMBER.NTX.
int ntx2 = -1; // ...of CALLEDBY.NTX.
SC_DBFRINFO rinfo;
SC_FIELD *finfo = NULL;
int f_member; // Field handles for MEMBER,
int f_calledby; // CALLEDBY, PHONE, and NAME
int f_phone; // fields in CALLTREE file.
int f_name;
// Given member/level, print callees.
int printtree (char *, int);
// Short-compare of strings.
int sstrcmp (char const *, char const *);
// Does file exist?
int file (char const *);
// Check for SoftC error and get out.
void errcheck (char const *);
// Deallocation and file closes.
void cleanup (void);
// Return .TRUE. if null string.
int nil (const char *);
// Return .TRUE. if all whitespace.
int empty (const char *);
//
// Open CALLTREE with MEMBER and CALLEDBY indexes.
// Then just call printlist() with the
// command-line arg.
//
int main (int argc, char *argv[])
{
int flong;
atexit (cleanup);
scdinit (20, 0);
scddopenx (&dbf, "CALLTREE.DBF", SC_RDONLY);
errcheck ("Opening CALLTREE.DBF");
scddrinfo (dbf, &rinfo);
finfo = new SC_FIELD [rinfo.numflds];
scddfinfo (dbf, &flong, finfo);
scddfnam2no (dbf, &f_member, "MEMBER");
scddfnam2no (dbf, &f_calledby, "CALLEDBY");
scddfnam2no (dbf, &f_phone, "PHONE");
scddfnam2no (dbf, &f_name, "NAME");
if (!file ("MEMBER.NTX")) {
long lRec;
char buffer[7];
scdccreate ("MEMBER.NTX", SC_CKEY | SC_UNIQUE,
"MEMBER", 3, 0);
scdcopenx (&ntx1, "MEMBER.NTX",
SC_RDWR | SC_EXCLUDE | SC_BUFFER);
cout << "Indexing on MEMBER...\n";
for (lRec = 1L; ; lRec++) {
if (scddrget (dbf, lRec) == SC_SKFAIL) {
sceclr();
break;
}
errcheck ("Indexing on MEMBER.");
scddfgets (dbf, 0, buffer);
scdckadd (ntx1, buffer, lRec);
cout << '\r' << lRec << " records indexed";
}
cout << '\n';
scdcclose (ntx1);
}
scdcopenx (&ntx1, "MEMBER.NTX", SC_RDONLY);
errcheck ("Opening MEMBER.NTX");
if (!file ("CALLEDBY.NTX")) {
long lRec;
char buffer[7];
scdccreate ("CALLEDBY.NTX",
SC_CKEY | SC_UNIQUE,
"CALLEDBY+MEMBER", 6, 0);
scdcopenx (&ntx2, "CALLEDBY.NTX",
SC_RDWR | SC_EXCLUDE | SC_BUFFER);
cout << "Indexing on CALLEDBY+MEMBER...\n";
for (lRec = 1L; ; lRec++) {
if (scddrget (dbf, lRec) == SC_SKFAIL) {
sceclr();
break;
}
errcheck ("Indexing on CALLEDBY+MEMBER.");
scddfgets (dbf, f_calledby, buffer);
scddfgets (dbf, f_member,
buffer + finfo[f_calledby].len);
scdckadd (ntx2, buffer, lRec);
cout << '\r' << lRec << " records indexed";
}
cout << '\n';
scdcclose (ntx2);
}
scdcopenx (&ntx2, "CALLEDBY.NTX", SC_RDONLY);
errcheck ("Opening CALLEDBY.NTX");
printtree (argc > 1 ? argv[1] : "", 0);
}
//
// printtree (char *cpFr, int npLv);
//
// Recursively print out all people called by "cpFr."
//
// Parameters:
//
// cpFr ASCIIZ string indicating caller's number.
// npLv Indicates "level" of output.
//
int printtree (char *cpFr, int npLv)
{
char member[4]; // Assume DBF: MEMBER C 3
char calledby[4]; // CALLEDBY C 3
char phone[8]; // PHONE C 7
char name[31]; // NAME C 30
char keybuffer[50]; // Buffer for key values, natch.
long nRec; // Current record number.
int nScCd; // SoftC error code.
register int i;
sceclr();
strcpy (keybuffer, cpFr);
nScCd = scdckfind (
ntx2,
(void *) keybuffer,
&nRec,
SC_FIRST);
// The index now points to the first matching
// record, if any. Now read in sequence until
// there is a non-matching record. Exit on
// error (code < 0) or end-of-file (code == SC_END).
while (nScCd >= 0 && nScCd != SC_END) {
// Get a record and ensure a match.
scddrget (dbf, nRec);
scddfgets (dbf, f_calledby, calledby);
if (nil (cpFr) ? !empty (calledby)
: sstrcmp (calledby, cpFr))
break;
// Break record into fields.
scddfgets (dbf, f_member, member);
scddfgets (dbf, f_name, name);
scddfgets (dbf, f_phone, phone);
for (i = 0; i < npLv; i++) cout << '\t';
cout << trim (name);
if (!empty (phone))
cout << " (" + substr (phone, 0, 3) + ;
"-" + substr (phone, 3) + ")";
cout << '\n';
// This recursive call changes the index
// pointer information:
printtree (member, npLv + 1);
// Now to fix index pointer:
nScCd = scdckfind (
ntx2,
(void *) keybuffer,
&nRec,
SC_EXACT);
// And go to the next record. This
// won't work in the case of duplicate
// keys, by the way.
if (nScCd >= 0)
nScCd = scdcknext (
ntx2,
(void *) keybuffer,
&nRec);
}
errcheck ("Printing call list");
return nScCd;
}
//---------- Minor support functions ----------//
int sstrcmp (char const *a, char const *b)
{
register int i;
for (i = 0; a[i] && b[i]; i++)
if (a[i] != b[i]) return (a[i] - b[i]);
return 0;
}
int file (const char *cName)
{
struct ffblk ff;
return (!findfirst (cName, &ff, 0));
}
void errcheck (char const *cText)
{
if (sc_code < 0) {
cout << "SoftC error " << sc_code << '\n';
cout << scemsg() << '\n';
cout << cText;
exit (-1);
}
}
void cleanup (void)
{
scddclose (dbf);
scdcclose (ntx1);
scdcclose (ntx2);
if (finfo != NULL)
delete finfo;
scdterm();
}
int nil (const char *s)
{
return (s[0] == '\0');
}
int empty (const char *s)
{
register int i;
for (i = 0; s[i]; i++)
if (!isspace (s[i])) return 0;
return 1;
}
--
Mark W. Schumann/3111 Mapledale Avenue/Cleveland, Ohio 44109-2447 USA
Domain: mark@whizbang.wariat.org CIS: 73750,3527
"Now when I tell people I'm Slovak, they won't think I'm Czech."
--My wife Judy (Mravetz) Schumann remarking upon the Czech/Slovak split