Category : Files from Magazines
Archive   : CUJ9209.ZIP
Filename : SCHUM2.CPP

 
Output of file : SCHUM2.CPP contained in archive : CUJ9209.ZIP
/*

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: [email protected]

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
#include

#include
#include
#include
#include

#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: [email protected] 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



  3 Responses to “Category : Files from Magazines
Archive   : CUJ9209.ZIP
Filename : SCHUM2.CPP

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/