home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume18
/
geneal
/
part03
/
family.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-08
|
9KB
|
334 lines
/* family.c - produce a family information page
* Written by Jim McBeath (jimmc) at SCI
*
* Revision history:
* 24-Jan-85 Jim McBeath Remove redundant declaration of gendp
* 27-Jan-85 Jim McBeath Use fgbslist; change fgclist to bclist
* 29-Jan-85 Jim McBeath convert to 7-char-distinct names
* 14-Feb-85 (Ian Darwin) remove mnumstr (unused variable)
* 24.Aug.87 jimmc Add Label stuff, add BUR info
* 14.Sep.87 jimmc Add addr stuff
* 27.Oct.87 jimmc General cleanup; call fggen to get GEN info
* 4.Jan.88 jimmc Make printindented not static
* 8.Jan.88 jimmc Allow lists of families to be printed
*/
#include <stdio.h>
#include <ctype.h>
#include "geneal.h"
#include "pagemap.h"
#define PAGEWID 80
#define LEFTMARGIN 4
#define RIGHTMARGIN 4
#define CENTERMARGIN 2
#define LEFTCOL ((PAGEWID-LEFTMARGIN-RIGHTMARGIN-CENTERMARGIN)/2)
#define RIGHTCOL (PAGEWID-LEFTMARGIN-RIGHTMARGIN-CENTERMARGIN-LEFTCOL)
#define ADDRCOL (LEFTMARGIN+20)
#define SPOUSEOFFSET 10
#define TBLOCKSIZE 1000
#define NOTEMAX 500
struct tblock { /* a text block */
int width; /* length of longest line */
int lines; /* number of lines */
char *text[TBLOCKSIZE]; /* the text pointers */
};
extern int dataStatus;
extern char *dataErrStrs[];
extern char *Label;
int notenum;
int notecount; /* for storing the footnotes */
char *notes[NOTEMAX];
printindented(indent,str)
int indent;
char *str;
{
if (!str || !str[0]) return;
fprintf(outfp,"%*s", indent, "");
for (; *str; str++) {
if (*str == '\n') {
fprintf(outfp,"\n%*s", indent, "");
}
else putc(*str,outfp);
}
putc('\n',outfp);
}
/*..........*/
int /* 0 if all OK */
family(ac,av)
int ac; /* number of families */
int *av; /* list of family id numbers */
{
int i,t;
t = 0;
for (i=0; i<ac; i++) {
if (i>0) fprintf(outfp,sepstr);
t += family1(av[i]);
}
return t;
}
/*..........*/
int /* 0 if OK */
family1(famnum)
int famnum; /* the family to give info about */
{
int rtype;
char *famname, *husname, *wifename;
char *huslname, *wifelname;
int husnum, wifenum;
char *headerline;
int i, cnum, clist[1000];
char *ss;
int addrnum;
char *addr;
char *phone;
notecount=notenum=0;
rtype = fgtype(famnum);
if (rtype<=0) {
warning("no such record number %d", famnum);
return 1;
}
if (rtype!='F') {
warning("record %d is not a family", famnum);
return 1;
}
famname = fgstr(famnum,"N"); /* get the family name */
husnum = fgnum(famnum,"H"); /* get husband and wife index nums */
wifenum = fgnum(famnum,"W");
husname = fgbname(husnum);
wifename = fgbname(wifenum);
huslname = fgstr(husnum,"LN");
wifelname = fgstr(wifenum,"LNM");
if (wifelname==0 || wifelname[0]==0) wifelname = fgstr(wifenum,"LN");
if (huslname && huslname[0]==0) huslname=0;
if (wifelname && wifelname[0]==0) wifelname=0;
if (famname && famname[0]==0) famname=0;
if (husname==0 || husname[0]==0) husname = "???";
if (wifename==0 || wifename[0]==0) wifename = "???";
if (famname && (huslname==0 || strcmp(famname,huslname)!=0))
headerline =
tprintf("%s - %s & %s", famname, husname, wifename);
else
headerline = tprintf("%s & %s", husname, wifename);
strup(headerline);
if (Gflag['N'] && Gflag['n']) {
ss = tprintf("[%d]: %s",famnum,headerline);
free(headerline);
headerline = ss;
}
printindented(LEFTMARGIN,Label);
printindented(LEFTMARGIN,headerline);
fprintf(outfp,"\n");
printpair(0,famnum,husnum, wifenum); /* print data about parents */
addrnum = fgnum(famnum,"ADDR");
if (Gflag['a'] && addrnum>0) { /* print address if known */
addr = fgstr(addrnum,"ADDR");
printindented(ADDRCOL,addr);
phone = fgstr(addrnum,"PHONE");
printindented(ADDRCOL,phone);
fprintf(outfp,"\n");
}
cnum = fgbclist(famnum,clist);
if (cnum==0) {
#if 0 /* be silent about no children... */
printindented(LEFTMARGIN,"NO CHILDREN");
#endif
}
else {
fprintf(outfp,"%*s%*s%*s%s\n\n",
LEFTMARGIN, "", -LEFTCOL, "CHILDREN",
CENTERMARGIN, "", "SPOUSES OF CHILDREN");
for (i=0; i<cnum; i++) {
int childnum, mgnum, spousenum, chusnum, cwifenum;
int scount,slist[1000],mnum;
childnum = clist[i];
scount = fgbslist(childnum,slist);
for (mnum=0; mnum<scount; mnum++) {
/* until we run out of marriages */
mgnum = slist[mnum];
chusnum = fgnum(mgnum, "H");
cwifenum = fgnum(mgnum, "W");
if (childnum==chusnum) spousenum=cwifenum;
else if (childnum==cwifenum) spousenum=chusnum;
else {
warning("person %d claims marriage %d, but not vice-versa!",
childnum, mgnum);
spousenum= -1;
}
printpair(mnum,mgnum,childnum,spousenum);
}
if (scount==0) printpair(0,-1,childnum,-1);
/* print the individual if no marriage */
}
}
if (notecount>0) { /* if we accumulated any notes */
printindented(LEFTMARGIN, "-----------------------");
for (i=0; i<notecount; i++)
printindented(LEFTMARGIN, notes[i]);
}
return 0;
}
/*..........*/
printpair(n,mn,cn,sn) /* print info about a couple */
int n; /* which marriage in the list this is; -1=only one */
int mn; /* marriage number */
int cn; /* primary person number */
int sn; /* spouse number */
{
struct tblock cntb, sntb; /* where to store data */
int i, max;
fampdat(n,mn,cn,&cntb); /* get the data */
fampdat(-1,mn,sn,&sntb);
/* decide if they should both be on the same lines or not */
if (cntb.width>LEFTCOL || sntb.width>RIGHTCOL) { /* separate */
printtb(&cntb,LEFTMARGIN); /* output the first one */
printtb(&sntb,LEFTMARGIN+SPOUSEOFFSET); /* output spouse */
}
else { /* both on the same line */
if (cntb.lines > sntb.lines) max = cntb.lines;
else max = sntb.lines;
for (i=0; i<max; i++) {
if (i>=cntb.lines)
printindented(
-(LEFTMARGIN+CENTERMARGIN+LEFTCOL),
sntb.text[i]);
else if (i>=sntb.lines)
printindented(LEFTMARGIN, cntb.text[i]);
else
/*** Problems here if field in database was > 1 line */
fprintf(outfp,"%*s%*s%*s%s\n", LEFTMARGIN, "",
-LEFTCOL, cntb.text[i], CENTERMARGIN,
"", sntb.text[i]);
}
fprintf(outfp,"\n");
}
}
/*..........*/
printtb(b,offset) /* print a text block */
struct tblock *b;
int offset; /* left margin offset */
{
int i;
for (i=0; i<b->lines; i++)
printindented(offset, b->text[i]);
if (b->lines!=0) fprintf(outfp,"\n");
}
/*..........*/
fampdat(i,m,n,b) /* get a tblock about a person */
int i; /* iteration number to determine how to format */
int m; /* marriage number */
int n; /* the person to get info about */
struct tblock *b; /* where to put the data */
{
char *name, *birth, *death, *buried, *marriage;
b->lines = b->width = 0; /* clear it out first */
if (n<=0) return;
name = fgbname(n);
birth = fgbirth(n);
death = fgdeath(n);
buried = fgburied(n);
marriage = fgnmarriage(m);
if (i<=0) {
addtline(name,b);
if (birth && *birth) addtline(birth,b);
if (death && *death) addtline(death,b);
if (buried && *buried) addtline(buried,b);
if (i==0) {
if (marriage && *marriage) addtline(marriage,b);
addnots(n,m,b); /* add general comment notes */
}
else /* i== -1 */
addnots(n,-1,b); /* don't add marriage notes */
}
else {
if (marriage && *marriage)
marriage = tprintf("re-%s", marriage);
else marriage = "remarried:";
addtline(marriage,b);
addnots(-1,m,b);
}
}
/*..........*/
addnots(n,m,b) /* add general comment notes to a block */
int n; /* index of person */
int m; /* index of marriage */
struct tblock *b; /* text block to add to */
{
addnote(n,b,"");
addnote(m,b," (m)");
}
/*..........*/
addnote(n,b,ss) /* add general comment notes to a block */
int n; /* index of person */
struct tblock *b; /* text block to add to */
char *ss; /* note indicator string */
{
char *gencom;
int lcount;
int hlen;
int t;
lcount = 0;
hlen = strlen(ss)+sizeof("Note")+2;
gencom = fggen(n);
lcount += countlines(gencom);
if (lcount==1 && ((t=strlen(gencom)+hlen)<=b->width||t<LEFTCOL)) {
/* if we have one relatively short string, do it in-line */
addtline(tprintf("[Note%s: %s]", ss, gencom),b);
}
else if (lcount>0) {
addtline(tprintf("[Note %d%s]", 1+notenum, ss),b);
notes[notecount++] = tprintf("Note %d%s:", 1+notenum++, ss);
notes[notecount++] = gencom; /* add string to notes */
notes[notecount++] = "";
}
}
/*..........*/
addtline(ss,b) /* add a line to a tblock */
char *ss; /* the string to add */
struct tblock *b; /* the block to add to */
{
int l;
if (b->lines >= TBLOCKSIZE) {
warning("tblock overflow!");
return; /* ignore the addition */
}
b->text[b->lines++] = ss; /* add in the string */
l = strlen(ss);
if (l> b->width) b->width=l; /* keep track of width */
}
/* end */