Geneal (part 3 of 3) (debugged version)
Terry L. Ridder
tlr at umcp-cs.UUCP
Sat Sep 14 09:10:54 AEST 1985
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# CHANGES
# Makefile
# README
# gbrowse.c
# geneal.1
# geneal.c
# geneal.h
# geneal.man
# genealogy.dat
# index.c
# index.h
# indivs.c
# This archive created: Thu Sep 12 22:20:31 1985
# By: Terry L. Ridder (The Terry L. Ridder family)
export PATH; PATH=/bin:$PATH
echo shar: extracting "'CHANGES'" '(4172 characters)'
if test -f 'CHANGES'
then
echo shar: will not over-write existing file "'CHANGES'"
else
sed 's/^ X//' << \SHAR_EOF > 'CHANGES'
X Changes made by Terry L. Ridder
X
X The tprintf function has been changed from calling vsprintf to
X calling sprintf. The reason for this is that the version of
X geneal for Unix Sys V was to flaky. I could not trust the
X changes made to work the same way on different Unix Sys V
X installations.
X
X I have still included the file vsprintf.c in the distribution
X of geneal. I am rewriting vsprintf using the varargs.h and
X the example given in varargs(3).
X
X The Makefile has been changed to reflect that vsprintf is no
X longer needed by geneal. The Makefile has also been changed
X in that there is now a define for USG. If USG is defined the
X there are the necessary define's in place to take care of the
X switch of 'index' -> 'strchr' and 'rindex' -> 'strrchr'.
X
X
X The errorman.c file has been changed from calling vsprintf to
X call sprintf. The function errormsg is not used in the geneal
X program.
X
X The original file GENEAL.DOC was rewritten into a manual page
X , which is now called 'geneal.1'. The file geneal.man
X is the result of the cmd 'nroff -man geneal.1 > geneal.man'
X
X The original file PGMR.DOC was rewritten into a nroff file using
X ms macros. The file is now called pgmr.doc. The file pgmr.man
X is the result of the cmd 'nroff -ms pgmr.doc > pgmr.man'.
X
X All files are now in the style that I normally use in C programs.
X
X i.e. if (expression) for (expression) while (expression)
X { { {
X .... ..... ....
X } } }
X
X
X if (expression)
X {
X ....
X }
X else where '....' is any number of statements.
X {
X ....
X }
X
X Changes made by Terry L. Ridder
X
X Original Variable Name Changed to
X ====================== ==========
X ac argc
X ar argv
X
X chusbandnum chisnum
X cwifenum chernum
X
X husbandlname hislname
X husbandname hisname
X husbandnum hisnum
X
X marriagenum marnum
X
X wifelname herlname
X wifename hername
X wifenum hernum
X
X spousenum sonum
X spousestr sostr
X
X famgetbirth() fgbirth()
X famgetbirthdeath() fgbegend()
X famgetbname() bname()
X famgetbstr() bstr()
X famgetclist() fgclist()
X famgetfname() fname()
X famgetmarriage() fgmar()
X famgetnum() fgnum()
X famgetstr(0 fgstr()
X famgettname() tname()
X
X Files Changed What Changed
X ============= ==================================
X famgetdat.c famgetbstr() -> bstr()
X famgetdat.c famgetbirth() -> fgbirth()
X famgetdat.c famgetbirthdeath() -> fgbegend()
X famgetdat.c famgetbname() -> bname()
X famgetdat.c famgetbstr() -> bstr()
X famgetdat.c famgetclist() -> fgclist()
X famgetdat.c famgetfname() -> fname()
X famgetdat.c famgetmarriage() -> fgmar()
X famgetdat.c famgetnum() -> fgnum()
X famgetdat.c famgetstr(0 -> fgstr()
X famgetdat.c famgettname() -> tname()
X
X family.c famgetbstr() -> bstr()
X family.c famgetbirth() -> fgbirth()
X family.c famgetbname() -> bname()
X family.c famgetclist() -> fgclist()
X family.c famgetmarriage() -> fgmar()
X family.c famgetnum() -> fgnum()
X family.c famgetstr(0 -> fgstr()
X family.c chusbandnum -> chisnum
X family.c cwifenum -> chernum
X family.c husbandlname -> hislname
X family.c husbandname -> hisname
X family.c husbandnum -> hisnum
X family.c marriagenum -> marnum
X family.c wifelname -> herlname
X family.c wifename -> hername
X family.c wifenum -> hernum
X family.c spousenum -> sonum
X family.c spousestr -> sostr
X
X
X famtree.c famgetbirthdeath() -> fgbegend()
X famtree.c famgetnum() -> fgnum()
X famtree.c famgetstr(0 -> fgstr()
X famtree.c famgettname() -> tname()
X
X geneal.c ac -> argc
X geneal.c ar -> argv
X
X gbrowse.c famgetbstr() -> bstr()
X
X indivs.c famgetbstr() -> bstr()
X indivs.c famgetbirth() -> fgbirth()
X indivs.c famgetbirthdeath() -> fgbegend()
X indivs.c famgetbname() -> bname()
X indivs.c famgetclist() -> fgclist()
X indivs.c famgetfname() -> fname()
X indivs.c famgetmarriage() -> fgmar()
X indivs.c famgetnum() -> fgnum()
X indivs.c famgettname() -> tname()
X
SHAR_EOF
if test 4172 -ne "`wc -c < 'CHANGES'`"
then
echo shar: error transmitting "'CHANGES'" '(should have been 4172 characters)'
fi
chmod +x 'CHANGES'
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(1818 characters)'
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^ X//' << \SHAR_EOF > 'Makefile'
XCFLAGS = -v -DUSG=1
X
XLINTFLAGS =
X
XDEST = .
X
XEXTHDRS = /usr/include/ctype.h \
X /usr/include/stdio.h
X
XHDRS = famtree.h \
X geneal.h \
X pagemap.h
X
XLDFLAGS =
X
XLINKER = cc
X
XMAKEFILE = Makefile
X
XOBJS = dataman.o \
X errorman.o \
X famgetdat.o \
X family.o \
X famtree.o \
X gbrowse.o \
X geneal.o \
X index.o \
X indivs.o \
X pagemap.o \
X strsav.o \
X tprintf.o \
X xalloc.o
X
XLIBS =
X
XPRINT = pr
X
XPROGRAM = geneal
X
XSRCS = dataman.c \
X errorman.c \
X famgetdat.c \
X family.c \
X famtree.c \
X gbrowse.c \
X geneal.c \
X index.c \
X indivs.c \
X pagemap.c \
X strsav.c \
X tprintf.c \
X xalloc.c
X
Xall: $(PROGRAM)
X
X$(PROGRAM): $(OBJS) $(LIBS)
X @echo -n "Loading $(PROGRAM) ... "
X @$(LINKER) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM)
X @echo "done"
X
Xclean:; @rm -f $(OBJS)
X
Xdepend:; @echo Updating makefile
X @mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST)
X
Xindex:; @ctags -wx $(HDRS) $(SRCS)
X
Xlint:; lint $(LINTFLAGS) $(SRCS) $(LINTLIBS)
X
Xinstall: $(PROGRAM)
X @echo Installing $(PROGRAM) in $(DEST)
X @install -s $(PROGRAM) $(DEST)
X
Xprint:; @$(PRINT) $(SRCS) $(HDRS)
X
Xprogram: $(PROGRAM)
X
Xtags: $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS)
X
Xupdate: $(DEST)/$(PROGRAM)
X
X$(DEST)/$(PROGRAM): $(SRCS) $(LIBS) $(HDRS) $(EXTHDRS)
X @make -f $(MAKEFILE) DEST=$(DEST) install
X
X###
Xdataman.o: /usr/include/stdio.h geneal.h
Xerrorman.o: /usr/include/stdio.h
Xfamgetdat.o: /usr/include/stdio.h geneal.h famtree.h
Xfamily.o: /usr/include/stdio.h /usr/include/ctype.h geneal.h pagemap.h
Xfamtree.o: /usr/include/stdio.h geneal.h famtree.h pagemap.h
Xgbrowse.o: geneal.h
Xgeneal.o: /usr/include/stdio.h /usr/include/ctype.h geneal.h
Xindex.o: geneal.h
Xindivs.o: geneal.h
Xpagemap.o: pagemap.h /usr/include/stdio.h
Xxalloc.o: /usr/include/stdio.h
SHAR_EOF
if test 1818 -ne "`wc -c < 'Makefile'`"
then
echo shar: error transmitting "'Makefile'" '(should have been 1818 characters)'
fi
chmod +x 'Makefile'
fi # end of overwriting check
echo shar: extracting "'README'" '(1887 characters)'
if test -f 'README'
then
echo shar: will not over-write existing file "'README'"
else
sed 's/^ X//' << \SHAR_EOF > 'README'
XThe GENEAL Program
XWritten by Jim McBeath (jimmc) at SCI
XModified by Terry L. Ridder (tlr) at The Terry L. Ridder Family
X
Xlast edit 20-Jan-85 16:55:25 by jimmc (Jim McBeath)
Xlast edit 30-Aug-85 01:29:00 by tlr (Terry L. Ridder)
X
XThis file describes what other files exist and what you will have to
Xdo in order to make geneal useful to you.
X
XFiles of interest:
X *.[ch] The source files for geneal.
X
X Makefile Exactly that.
X
X README What you are looking at right now.
X
X geneal.l Manual page for geneal. nroff -man geneal.l to
X generate geneal.man.
X
X geneal.man Manual page for geneal. Describes (briefly) what
X geneal is all about. Gives list of options.
X
X pgmr.doc nroff file for prog.man. nroff -ms pgmr.doc > pgmr.man
X
X pgmr.man Programmer's documentation. Gives more detail about some
X of the source files. Read this if you are going to make
X any changes to the program or if you need to look for bugs.
X
X genealogy.dat The data file. This is a sample file for you to use
X as a template for creating your own data file.
X
X family.1003 Sample output file produced by "geneal -f 1003".
X
XWhat to do (after unpacking):
X1. Read geneal.man.
X2. Make the program. You should be able to simply issue a "make" command.
X If you wish, you can test it out at this point on the sample data file
X and make sure that it works.
X3. Make your own data file. Delete all of the supplied data file except
X record 0 (the description of the data format). Add your own data in
X the same format.
X4. Run the program. There are numerous checks for data consistency, so
X you should get error messages if things do not point to each other
X properly. These are typically easy to fix.
X5. If you want to make changes, read pgmr.man first.
X6. Send us your comments and improvements.
X
X
X -Jim McBeath
X 15-Jan-1985
X -Terry L. Ridder
X 30-Aug-1985
SHAR_EOF
if test 1887 -ne "`wc -c < 'README'`"
then
echo shar: error transmitting "'README'" '(should have been 1887 characters)'
fi
chmod +x 'README'
fi # end of overwriting check
echo shar: extracting "'gbrowse.c'" '(1260 characters)'
if test -f 'gbrowse.c'
then
echo shar: will not over-write existing file "'gbrowse.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'gbrowse.c'
X/* gbrowse.c - browse through the genealogy file */
X/* Written by Jim McBeath (jimmc) at SCI */
X/* last edit 19-Jan-85 09:08:30 by jimmc (Jim McBeath) */
X/* last edit 31-Aug-85 13:00:00 by tlr (Terry L. Ridder) */
X
X#include "geneal.h"
X
Xextern char *gets();
X
Xint /* 0 if OK */
Xgbrowse() /* browse the database */
X{
Xchar *ss;
Xchar lbuf[1000];
Xchar tbuf[1000];
Xint n;
Xint t;
X
X indexes++; /* note we want to see all the index numbers */
X while (1) /* until a break takes us out */
X {
X printf(">"); /* give the browse prompt */
X ss = gets(lbuf); /* read in a line */
X if (ss == 0)
X {
X break; /* quit on eof */
X }
X if (lbuf[0] == 0)
X {
X continue; /* ignore blank lines */
X }
X t = sscanf(lbuf, "%d", &n); /* read his number */
X if (t != 1)
X {
X printf("numbers only, please\n");
X continue; /* read another line */
X }
X if (n <= 0)
X {
X continue;
X }
X t = bstr(n, "T", tbuf); /* see what the record type is */
X if (t == 0) /* if not there */
X {
X printf("bad record %d\n", n);
X continue;
X }
X if (strcmp(tbuf, "I") == 0)
X {
X indivs(n);
X }
X else if (strcmp(tbuf, "F") == 0)
X {
X family(n);
X }
X else
X {
X printf("unknown type code %s in record %d\n", tbuf, n);
X }
X/* continue the loop */
X }
X return 0;
X}
X
X/* end */
SHAR_EOF
if test 1260 -ne "`wc -c < 'gbrowse.c'`"
then
echo shar: error transmitting "'gbrowse.c'" '(should have been 1260 characters)'
fi
chmod +x 'gbrowse.c'
fi # end of overwriting check
echo shar: extracting "'geneal.1'" '(3143 characters)'
if test -f 'geneal.1'
then
echo shar: will not over-write existing file "'geneal.1'"
else
sed 's/^ X//' << \SHAR_EOF > 'geneal.1'
X.TH GENEAL LOCAL 8/28/85
X.SH NAME
Xgeneal \- genealogy program
X.SH SYNOPSIS
X.B Geneal
X[ option ] ...
X[ file ]
X.SH DESCRIPTION
X.I Geneal
Xis a program to read a database of family relations in the named
X.I file
Xand print the information out in various formats.
X.PP
XIf no
X.I file
Xargument is present, the default file,
X.I genealogy.dat
X, is read.
X.PP
XIt deals with
Xfamilies and individuals, each identified by a unique integer.
XThe database contains information such as
X.I birth
X,
X.I death
Xand
X.I marriage
Xdates and places (if you know them!), relations between
Xpeople (i.e. what children belong to X, are you my mother),
Xand miscellaneous information of general interest.
XThe program can read the information for a specified individual
Xand output it in a specified format. At the moment there are two
Xformats (only one of which is "real"): the tree, and the family
Xpage. The tree format is only a tiny bit implemented, so it's
Xnot very useful yet. The family page gives information about
Xan entire family (one generation), i.e. parents, children, and
Xchildrens's spouses. More formats can easily be added (and will
Xbe in the future!).
X
XGeneal expects one argument on the command line, which is the index
Xnumber of the person or family to center the data search/output on.
X.PP
XThe options available are:
X.TP "w'\f3\-F\f1name 'u"
X.BI \-f
Xproduce a family information page
X.TP
X.BI \-h
Xgive this help message (try this in case this man page is wrong!)
X.TP
X.BI \-i
Xproduce information about an individual
X.TP
X.BI \-s
Xuse a short form of output
X.TP
X.BI \-t
Xproduce a tree (not implemented very far!)
X.TP
X.BI \-D
Xdebug data routines
X.TP
X.BI \-F file
Xuse the specified file as datafile
X.TP
X.BI \-I
Xdebug index routines
X.TP
X.BI \-N
Xoutput internal index numbers with all names
X.PP
XIf no format switches (-f, -i, -t) are given, browse mode is entered.
XThe two debug switches (-D and -I) will probably not be useful to you
Xunless you are familiar with the dataman and index routines which they
Xapply to.
X
X.SH EXAMPLE
XIndividuals or families are specified by index number. Thus the
Xcommand to output the family data page for a particular family
Xwould be
X.IP
X.nf
X geneal -f 1025
X.fi
Xwhere 1025 is the index number for that family.
X.SH NOTES
XThere is some flexibility in the data file as to what numbers you
Xuse as index numbers. The authors have adopted the convention that individuals
Xare numbered starting at 1 and families starting at 1000 (when I get
X1000 individuals, I will start the next group at 10000). You may
Xwant to use different conventions, e.g. odd numbers for males, even
Xfor females; families starting at a higher number; or whatever.
X.SH FILES
X.nf
X genealogy.dat The database file. This is a sample
X file for you to use as a template
X for creating your own data file.
X
X family.1003 Sample output file produced by
X "geneal -f 1003".
X
X pgmr.doc Programmer's documentation. Gives
X more details about some of the source
X files. Read this if you need to look
X for bugs.
X.fi
X.SH AUTHOR
XJim McBeath (original author)
X.br
XTerry L. Ridder (ported geneal to Version 7 and SYS V)
SHAR_EOF
if test 3143 -ne "`wc -c < 'geneal.1'`"
then
echo shar: error transmitting "'geneal.1'" '(should have been 3143 characters)'
fi
chmod +x 'geneal.1'
fi # end of overwriting check
echo shar: extracting "'geneal.c'" '(4571 characters)'
if test -f 'geneal.c'
then
echo shar: will not over-write existing file "'geneal.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'geneal.c'
X/* geneal - manipulate family trees, etc. */
X/* Written by Jim McBeath (jimmc) at SCI */
X/* last edit 19-Jan-85 08:17:08 by jimmc (Jim McBeath) */
X/* last edit 10-Sept-85 07:16:00 by tlr (Terry L. Ridder) */
X
X#include "geneal.h"
X#include <ctype.h>
X
X#define HELP_EXIT 2
X
Xextern char *getData(), *rindex();
X
Xchar *Progname; /* name of the program */
Xextern int dataDebug; /* flag for debugging data routines */
Xextern int indexDebug; /* flag for debugging index routines */
X
Xstruct dpoint *initDataFile();
Xstruct dpoint *gendp; /* data pointer for file */
Xchar *gendatfile="genealogy.dat"; /* filename for data file */
Xint indexes=0; /* set means output index numbers */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
Xint i, j;
Xint nval = 1;
Xint nsac = 0; /* non-switch argument count */
Xint fampage = 0; /* set means user wants a family info page */
Xint sflag = 0; /* set means use short form */
Xint iflag = 0; /* set means produce individual data page */
Xint tflag = 0; /* set means produce a tree */
Xint t; /* for status values */
X
X Progname = rindex(argv[0], '/'); /* program name */
X if (Progname == 0)
X {
X Progname = argv[0];
X }
X else
X {
X Progname++;
X }
X nval = 0; /* stays 0 if the user never asks for a number */
X for (i = 1; i < argc; i++) /* scan switches and args */
X {
X if (argv[i][0] == '-') for (j = 1; j > 0 && argv[i][j]; j++)
X /* check switches */
X switch (argv[i][j])
X {
X case 'f': /* produce family info page */
X fampage++;
X break;
X case 'h': /* give help */
X genhelp();
X exit(HELP_EXIT); /* don't continue */
X case 'i': /* individual information page */
X iflag++;
X break;
X case 's': /* short form */
X sflag++;
X break;
X case 't': /* produce a tree */
X tflag++;
X break;
X case 'D': /* debug data routines */
X dataDebug++;
X break;
X case 'F':
X if (argv[i][j+1])
X {
X gendatfile = argv[i]+(j+1);
X }
X else if (argv[++i])
X {
X gendatfile = argv[i];
X }
X else
X {
X fatalerr("no argument for -F switch");
X }
X j = -2; /* flag this string is used up */
X break;
X case 'I': /* debug index routines */
X indexDebug++;
X break;
X case 'N': /* output index numbers */
X indexes++;
X break;
X default:
X fatalerr("unknown switch %c in %s", argv[i][j], argv[i]);
X }
X else /* non-switch args */
X {
X switch (nsac++) /* non-switch arg count */
X {
X case 0: /* first arg is number to use */
X if (isdigit(argv[i][0]))
X {
X nval = atoi(argv[i]);
X }
X else
X {
X fatalerr("bad format for arg0 (must be a number)");
X }
X break;
X default: /* too many */
X fatalerr("unknown argument %s", argv[i]);
X }
X }
X }
X if (fampage + iflag + tflag > 1)
X {
X fatalerr("only one of -f, -i or -t may be selected");
X }
X gendp = initDataFile(gendatfile); /* get data file */
X if (gendp == 0)
X {
X fatalerr("can't open data file %s", gendatfile);
X }
X/* check for combinations which are not yet implemented */
X if (fampage && sflag)
X {
X warning("short form for family is not implemented");
X }
X if (iflag && !sflag)
X {
X warning("only short form available for individuals");
X }
X if (fampage) /* produce a family page if requested */
X {
X t = family(nval);
X }
X else if (iflag) /* produce info about individual */
X {
X t = indivs(nval);
X }
X else if (tflag) /* produce a family tree */
X {
X t = famtree(nval);
X }
X/* if no specific action was requested, do the default */
X else /* go browsing */
X {
X t = gbrowse();
X }
X if (t == 0) /* if no errors, exit w/o errors */
X {
X exit(0);
X }
X else
X {
X exit(1); /* errors */
X }
X}
X
X/*........../
X
X/* the help table */
Xchar *helptab[] = {
X"arg0 is the ID number of interest",
X"Switches:",
X"-f produce a family information page",
X"-h give this help message",
X"-i produce an individual (person) information page",
X"-s use a short form for the specified information",
X"-t produce a tree (this function is quite incomplete!)",
X"-D debug data routines",
X"-F file use the specified file as datafile",
X"-I debug index routines",
X"-N output internal index numbers with all names",
X"If no switches are given, the program enters browse mode.",
X0
X};
X
Xgenhelp() /* give help */
X{
Xint i;
X
X for (i = 0; helptab[i]; i++)
X {
X printf("%s\n", helptab[i]); /* print out the help table */
X }
X return;
X}
X
X/* end */
SHAR_EOF
if test 4571 -ne "`wc -c < 'geneal.c'`"
then
echo shar: error transmitting "'geneal.c'" '(should have been 4571 characters)'
fi
chmod +x 'geneal.c'
fi # end of overwriting check
echo shar: extracting "'geneal.h'" '(1372 characters)'
if test -f 'geneal.h'
then
echo shar: will not over-write existing file "'geneal.h'"
else
sed 's/^ X//' << \SHAR_EOF > 'geneal.h'
X/* geneal.h - general include stuff for geneal modules */
X/* Written by Jim McBeath (jimmc) at SCI */
X/* last edit 19-Jan-85 05:07:41 by jimmc (Jim McBeath) */
X/* last edit 10-Sept-85 07:19:00 by tlr (Terry L. Ridder) */
X
X#include <stdio.h>
X
X#define TBLSIZ 100
X
Xstruct tblblock {
X int repnum; /* number of indexes represented by this blk */
X int count; /* count of entries in this level */
X int tdata[TBLSIZ]; /* the actual data for this level */
X };
X
Xstruct toplevel {
X int numlevs; /* how deep the table is at it's deepest */
X struct tblblock *data; /* pointer to the top level */
X };
X
Xstruct dpoint {
X FILE *ff;
X struct toplevel *xx;
X };
X
X/* global variables */
Xstruct dpoint *gendp; /* data file index number */
Xextern int indexes; /* set means output index numbers w names */
X
X/* declare functions */
Xchar *index();
X
Xchar *getData();
Xchar *strsav();
Xchar *tprintf();
X
Xchar *fgstr(); /* originally char *famgetstr() */
Xchar *tname(); /* originally char *famgettname() */
Xchar *bname(); /* originally char *famgetbname() */
Xchar *fname(); /* originally char *famgetfname() */
Xchar *fgbirth(); /* originally char *famgetbirth() */
Xchar *fgdeath(); /* originally char *famgetdeath() */
Xchar *fgbegend(); /* originally char *famgetbirthdeath() */
Xchar *fgmar(); /* originally char *famgetmarriage() */
X
X/* end */
SHAR_EOF
if test 1372 -ne "`wc -c < 'geneal.h'`"
then
echo shar: error transmitting "'geneal.h'" '(should have been 1372 characters)'
fi
chmod +x 'geneal.h'
fi # end of overwriting check
echo shar: extracting "'geneal.man'" '(3740 characters)'
if test -f 'geneal.man'
then
echo shar: will not over-write existing file "'geneal.man'"
else
sed 's/^ X//' << \SHAR_EOF > 'geneal.man'
X
X
X
XGENEAL(LOCAL) UNIX Programmer's Manual GENEAL(LOCAL)
X
X
X
XNAME
X geneal - genealogy program
X
XSYNOPSIS
X Geneal [ option ] ... [ file ]
X
XDESCRIPTION
X _G_e_n_e_a_l is a program to read a database of family relations
X in the named _f_i_l_e and print the information out in various
X formats.
X
X If no _f_i_l_e argument is present, the default file,
X _g_e_n_e_a_l_o_g_y._d_a_t , is read.
X
X It deals with families and individuals, each identified by a
X unique integer. The database contains information such as
X _b_i_r_t_h , _d_e_a_t_h and _m_a_r_r_i_a_g_e dates and places (if you know
X them!), relations between people (i.e. what children belong
X to X, are you my mother), and miscellaneous information of
X general interest. The program can read the information for
X a specified individual and output it in a specified format.
X At the moment there are two formats (only one of which is
X "real"): the tree, and the family page. The tree format is
X only a tiny bit implemented, so it's not very useful yet.
X The family page gives information about an entire family
X (one generation), i.e. parents, children, and childrens's
X spouses. More formats can easily be added (and will be in
X the future!).
X
X Geneal expects one argument on the command line, which is
X the index number of the person or family to center the data
X search/output on.
X
X The options available are:
X
X -f produce a family information page
X
X -h give this help message (try this in case this man page
X is wrong!)
X
X -i produce information about an individual
X
X -s use a short form of output
X
X -t produce a tree (not implemented very far!)
X
X -D debug data routines
X
X -F_f_i_l_e
X use the specified file as datafile
X
X -I debug index routines
X
X
X
XPrinted 8/29/85 8/28/85 1
X
X
X
X
X
X
XGENEAL(LOCAL) UNIX Programmer's Manual GENEAL(LOCAL)
X
X
X
X -N output internal index numbers with all names
X
X If no format switches (-f, -i, -t) are given, browse mode is
X entered. The two debug switches (-D and -I) will probably
X not be useful to you unless you are familiar with the data-
X man and index routines which they apply to.
X
X
XEXAMPLE
X Individuals or families are specified by index number. Thus
X the command to output the family data page for a particular
X family would be
X
X
X geneal -f 1025
X where 1025 is the index number for that family.
X
XNOTES
X There is some flexibility in the data file as to what
X numbers you use as index numbers. The authors have adopted
X the convention that individuals are numbered starting at 1
X and families starting at 1000 (when I get 1000 individuals,
X I will start the next group at 10000). You may want to use
X different conventions, e.g. odd numbers for males, even for
X females; families starting at a higher number; or whatever.
X
XFILES
X genealogy.dat The database file. This is a sample
X file for you to use as a template
X for creating your own data file.
X
X family.1003 Sample output file produced by
X "geneal -f 1003".
X
X pgmr.doc Programmer's documentation. Gives
X more details about some of the source
X files. Read this if you need to look
X for bugs.
X
XAUTHOR
X Jim McBeath (original author)
X Terry L. Ridder (ported geneal to Version 7 and SYS V)
X
X
X
X
X
X
X
X
X
X
X
X
X
XPrinted 8/29/85 8/28/85 2
X
X
X
SHAR_EOF
echo shar: 48 control characters may be missing from "'geneal.man'"
if test 3740 -ne "`wc -c < 'geneal.man'`"
then
echo shar: error transmitting "'geneal.man'" '(should have been 3740 characters)'
fi
chmod +x 'geneal.man'
fi # end of overwriting check
echo shar: extracting "'genealogy.dat'" '(2829 characters)'
if test -f 'genealogy.dat'
then
echo shar: will not over-write existing file "'genealogy.dat'"
else
sed 's/^ X//' << \SHAR_EOF > 'genealogy.dat'
X0 Description of data format
X:Sample Data file for genealogy records.
X:All the information has been changed to protect the innocent.
X:last edit 20-Jan-85 16:41:45 by jimmc (Jim McBeath)
X:
X:File format:
X:Each record specifies either an individual or a family.
X:Each record has a unique index number.
X:Each record is separated by a blank line.
X:Each line within a record is an item of data.
X:Each item of data consists of a key, a colon, and a payload string.
X:Lines which start with a colon are comment lines.
X:The first line of each record starts with an integer which is
X:the index number for that record. The rest of that line is ignored.
X:
X:The fields used in this file are described in this record.
XT:Type of record: I for individual, F for family
X:fields in an individual record:
XLN:Last name (family name)
XLNM:Maiden name
XFN:First name
XMN:Middle names
XNN:Nickname
XB:Birthdate in the format dd-mmm-yyyy
XBP:Place of birth
XD:Date of death in the same format
XDP:Place of death
XP:Index number of parent's marriage
XS0:Index number of first marriage
XS1:Index number of second marriage
X:A family record contains information about a marriage and its offsprings.
X:fields in a family record:
XN:family name
XH:Index number of husband
XW:Index number of wife
XM:Date of marriage
XMD:Date of end of marriage
XMP:Place of marriage
XMDP:Place of end of marriage
XC:Index number list of children from this marriage
X:general fields:
XGEN0:General information of interest about that person.
XGEN1: etc.
XCOM0:Comments.
XCOM1: etc.
X:
X:first real record follows
X
X1 John Doe (1952)
XT:I
XLN:Doe
XFN:John
XMN:Michael
XNN:Norm
XB:10-Feb-1952
XBP:Anytown, USA
XP:1003
XS0:1001
X
X2 Andrew Doe (1921)
XT:I
XLN:Doe
XFN:Andrew
XMN:Q.
XB:3-Feb-1921
XBP:New York, NY
XS0:1003
XP:1004
X
X3 Elizabeth Smith Doe (1925)
XT:I
XLN:Doe
XLNM:Smith
XFN:Elizabeth
XMN:Nancy
XNN:Beth
XB:4-Mar-1925
XBP:Hauppauge, NY
XS0:1003
X
X4 Jane Jones Doe (1953)
XT:I
XLN:Doe
XLNM:Jones
XFN:Jane
XMN:Jill
XB:12-Dec-1953
XBP:Los Angeles, CA
XS0:1001
X
X5 Dave Doe (1949)
XT:I
XLN:Doe
XFN:David
XNN:Dave
XB:3-Jun-1949
XBP:Midville, USA
XP:1003
XS0:1002
X
X6 Kim Doe (1975)
XT:I
XLN:Doe
XFN:Kimberly
XMN:Janice
XNN:Kim
XB:5-Apr-1975
XBP:Oakland, CA
XP:1001
X
X8 Nancy Walker Doe (1950)
XT:I
XLN:Doe
XLNM:Walker
XFN:Nancy
XMN:M.
XB:Jul-1950
XS0:1002
X
X9 Hans Doe (ca 1900?)
XT:I
XLN:Doe
XFN:Hans
XB:ca. 1900?
XBP:Sweden
XS0:1004
X
X10 Lita ?? Doe (ca 1900?)
XT:I
XLN:Doe
XFN:Lita
XB:ca. 1900?
XS0:1004
X
XCOM0:Try to find maiden name in Oslo marriage records
X
X1001 John Doe and Jane Jones (1973)
XT:F
XN:Doe
XH:1
XW:4
XM:15-Jun-1973
XMP:San Franciso, CA
XC:6
X
X1002 Dave Doe and Nancy Walker (1975)
XT:F
XN:Doe
XH:5
XW:8
XM:6-Sep-1975
X
X1003 Andrew Doe and Elizabeth Simth (1948)
XT:F
XN:Doe
XH:2
XW:3
XM:3-Aug-1948
XMP:San Francisco, CA
XC:5,1
X
X1004 Hans Doe and Lita ?? (1919)
XT:F
XN:Doe
XH:9
XW:10
XM:1915
XMP:Oslo, Sweden?
XC:2
XGEN0:Stowed away on a ship in 1917 to come to America.
X
X:end of file
SHAR_EOF
if test 2829 -ne "`wc -c < 'genealogy.dat'`"
then
echo shar: error transmitting "'genealogy.dat'" '(should have been 2829 characters)'
fi
chmod +x 'genealogy.dat'
fi # end of overwriting check
echo shar: extracting "'index.c'" '(5783 characters)'
if test -f 'index.c'
then
echo shar: will not over-write existing file "'index.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'index.c'
X/* index - index handler for large pseudo-arrays */
X/* Written by Jim McBeath (jimmc) at SCI */
X/* last edit 10-Jan-85 07:59:39 by jimmc (Jim McBeath) */
X/* last edit 31-Aug-85 13:00:00 by tlr (Terry L. Ridder) */
X
X/* This module implements a very large pseudo-array. There are three
X entry points, to initialize a pseudo-array, to insert an item, and
X to read an item. The array contains integers (which can of course
X be used for another purpose, such as pointers to something else).
X
X Structure of a table:
X A table is a recursive structure which contains 2 words of size
X information and n words of pointers. The first word of size
X information tells how many entries are represented by this and
X all lower tables; the second word of size information tells how
X many entries are actually in this table. If the two numbers are
X the same, then the table is an end node which actually has the
X data entries in it.
X*/
X
X/*..........*/
X
X#include "geneal.h"
X
Xextern char *malloc(); /* added by tlr */
X
Xint indexDebug = 0; /* a debugging flag */
X
X/*..........*/
X
Xstruct toplevel * /* pointer to the structure for future calls */
XinitIndex() /* init a new index table */
X{
Xstruct toplevel *tt;
Xstruct tblblock *dd;
Xint i;
X
X tt = (struct toplevel *)malloc(sizeof(struct toplevel));
X /* get space for top level block */
X if (!tt)
X {
X return 0;
X }
X dd = (struct tblblock *)malloc(sizeof(struct tblblock));
X /* get space for top level table */
X if (!dd)
X {
X free((char *)tt);
X return 0;
X }
X tt->data = dd; /* save pointer in our block */
X tt->numlevs = 1; /* we always start with one level */
X dd->repnum = TBLSIZ;
X dd->count = TBLSIZ;
X for (i = 0; i < dd->count; i++)
X {
X dd->tdata[i] = 0; /* clear all data */
X }
X return tt; /* return pointer to top level block */
X}
X
X/*..........*/
X
XsetIndex(tt, ix, num) /* put index value into table */
Xstruct toplevel *tt; /* table to use */
Xint ix; /* the index where it goes */
Xint num; /* the value to put there */
X{
Xstruct tblblock *dd, *dd0;
Xint i;
X
X if (indexDebug)
X {
X printf("setIndex: index=%d, value=%d\n", ix, num);
X if (!tt)
X {
X printf("setIndex: no table index\n");
X }
X else if (!(tt->numlevs))
X {
X printf("setIndex: no numlevs\n");
X }
X else if (!(tt->data))
X {
X printf("setIndex: no data array\n");
X }
X }
X if (!tt)
X {
X return -1; /* check for errors */
X }
X if (!(tt->numlevs))
X {
X return -1;
X }
X if (!(tt->data))
X {
X return -1;
X }
X dd = tt->data; /* get data pointer */
X while (ix >= dd->repnum)
X { /* create a higher level */
X if (indexDebug)
X {
X printf("setIndex: %d(ix) > %d(repnum)\n", ix, dd->repnum);
X }
X dd0 = (struct tblblock *)malloc(sizeof(struct tblblock));
X /* get space for a higher level */
X if (!dd0)
X {
X return -1; /* error */
X }
X dd0->repnum = dd->repnum*TBLSIZ;
X dd0->count = TBLSIZ;
X for (i = 0; i < TBLSIZ; i++)
X {
X dd0->tdata[i] = 0; /* clear table */
X }
X dd0->tdata[0] = (int)dd; /* put in pointer to next level down */
X tt->data = dd0; /* put in new top-level pointer */
X tt->numlevs++;
X if (indexDebug)
X {
X printf("setIndex: numlevs=%d\n", tt->numlevs);
X }
X dd = dd0;
X }
X while (dd->repnum > dd->count)
X { /* scan down to the last level */
X if (indexDebug)
X {
X printf("setIndex: %d(repnum) > %d(count)\n",
X dd->repnum, dd->count);
X }
X dd0 = (struct tblblock *)(dd->tdata[ix/dd->count]);
X /* get pointer to next table lower */
X if (!dd0)
X { /* if no table there, have to make one */
X dd0 = (struct tblblock *)malloc(sizeof(struct tblblock));
X if (!dd0)
X {
X return -1; /* error */
X }
X dd0->repnum = dd->repnum/dd->count;
X dd0->count = TBLSIZ;
X for (i = 0; i < TBLSIZ; i++)
X {
X dd0->tdata[i] = 0; /* clear the new table */
X }
X dd->tdata[ix/dd->count] = (int)dd0; /* save pointer to it */
X }
X ix %= dd->count; /* lower the index */
X dd = dd0;
X }
X dd->tdata[ix] = num; /* put it in */
X if (indexDebug)
X {
X printf("setIndex: table %X, index %d, value %d\n",
X dd, ix, num);
X }
X return ix;
X}
X
X/*..........*/
X
Xint /* return value out of table */
X /* returns 0 if no entry */
XgetIndex(tt, ix)
Xstruct toplevel *tt;
Xint ix; /* the index to look for */
X{
Xstruct tblblock *dd, *dd0;
X
X if (indexDebug)
X {
X printf("getIndex: index=%d\n", ix);
X if (!tt)
X {
X printf("getIndex: no table\n");
X }
X else if (!tt->data)
X {
X printf("getIndex: no data array\n");
X }
X else if (!tt->numlevs)
X {
X printf("genIndex: no numlevs\n");
X }
X }
X if (!tt)
X {
X return 0; /* check for errors */
X }
X if (!tt->data)
X {
X return 0;
X }
X if (!tt->numlevs)
X {
X return 0;
X }
X dd = tt->data;
X if (ix >= dd->repnum)
X {
X if (indexDebug)
X {
X printf("getIndex: index %d > repnum %d\n", ix,dd->repnum);
X }
X return 0; /* we don't have them that high */
X }
X while (dd->repnum > dd->count)
X { /* scan down to bottom level */
X if (indexDebug)
X {
X printf("getIndex: %d(repnum) > %d(count)\n",
X dd->repnum, dd->count);
X }
X dd0 = (struct tblblock *)(dd->tdata[ix/dd->count]);
X /* get pointer to next level */
X if (!dd0)
X {
X if (indexDebug)
X {
X printf("getIndex: no table\n");
X }
X return 0; /* nothing there */
X }
X ix %= dd->count;
X dd = dd0;
X }
X if (indexDebug)
X {
X printf("getIndex: table %X, index %d, value %d\n",
X dd, ix, dd->tdata[ix]);
X }
X return dd->tdata[ix]; /* this is the data entry */
X}
X
X/* end of index */
SHAR_EOF
if test 5783 -ne "`wc -c < 'index.c'`"
then
echo shar: error transmitting "'index.c'" '(should have been 5783 characters)'
fi
chmod +x 'index.c'
fi # end of overwriting check
echo shar: extracting "'index.h'" '(584 characters)'
if test -f 'index.h'
then
echo shar: will not over-write existing file "'index.h'"
else
sed 's/^ X//' << \SHAR_EOF > 'index.h'
X/* index.h - definitions for index */
X/* Written by Jim McBeath (jimmc) at SCI */
X/* last edit 19-Jan-85 08:53:10 by jimmc (Jim McBeath) */
X/* last edit 31-Aug-85 13:00:00 by tlr (Terry L. Ridder) */
X
X#define TBLSIZ 100
X
Xstruct tblblock {
X int repnum; /* number of indexes represented by this blk */
X int count; /* count of entries in this level */
X int tdata[TBLSIZ]; /* the actual data for this level */
X };
X
Xstruct toplevel {
X int numlevs; /* how deep the table is at it's deepest */
X struct tblblock *data; /* pointer to the top level */
X };
X
X/* end */
SHAR_EOF
if test 584 -ne "`wc -c < 'index.h'`"
then
echo shar: error transmitting "'index.h'" '(should have been 584 characters)'
fi
chmod +x 'index.h'
fi # end of overwriting check
echo shar: extracting "'indivs.c'" '(4224 characters)'
if test -f 'indivs.c'
then
echo shar: will not over-write existing file "'indivs.c'"
else
sed 's/^ X//' << \SHAR_EOF > 'indivs.c'
X/* indivs.v - print out short form info about an individual */
X/* Written by Jim McBeath (jimmc) at SCI */
X/* last edit 19-Jan-85 08:05:47 by jimmc (Jim McBeath) */
X/* last edit 31-Aug-85 13:00:00 by tlr (Terry L. Ridder) */
X
X#include "geneal.h"
X
Xextern char *sprintf();
X
Xint /* 0 if OK */
Xindivs(n)
Xint n; /* the person's ID number */
X{
Xchar lbuf[1000];
Xchar *ss;
Xint pnum; /* parent family number */
Xint fnum; /* father's number */
Xint mnum; /* mother's number */
Xint mgnum; /* marriage number */
Xint snum; /* spouse's number */
Xint mhnum, mwnum;
Xchar mgstr[20]; /* used for building key string */
Xint i; /* loop counter */
Xint t; /* random numbers and status */
Xchar *sostr;
X
X bstr(n, "T", lbuf);
X if (lbuf[0] == 0 || strcmp(lbuf, "I") != 0)
X {
X warning("id %d is not an individual");
X return 1;
X }
X ss = fname(n);
X printf("Name: %s\n", ss);
X ss = fgbirth(n);
X if (ss && *ss)
X {
X printf("%s\n", ss);
X }
X ss = fgdeath(n);
X if (ss && *ss)
X {
X printf("%s\n", ss);
X }
X pnum = fgnum(n, "P"); /* get number of parent family */
X if (pnum > 0) /* if we got a family */
X {
X if (indexes)
X {
X printf("Parent family: %d\n", pnum);
X }
X fnum = fgnum(pnum, "H");
X if (fnum >= 0)
X {
X ss = fname(fnum);
X printf(" Father: %s\n", ss);
X ss = fgbegend(fnum);
X if (ss && *ss)
X {
X printf(" %s\n", ss);
X }
X }
X mnum = fgnum(pnum, "W");
X if (mnum >= 0)
X {
X ss = fname(mnum);
X printf(" Mother: %s\n", ss);
X ss = fgbegend(mnum);
X if (ss && *ss)
X {
X printf(" %s\n", ss);
X }
X }
X ss = fgmar(pnum);
X if (ss)
X {
X printf("Parent's marriage: %s\n", ss);
X }
X doiclist(pnum, "Sibling", "Siblings", n); /* do the siblings */
X }
X else /* no parent in this record */
X {
X if (indexes)
X {
X printf("No parent family specified\n");
X }
X }
X for (i = 0; ; i++) /* look at marriages */
X {
X sprintf(mgstr, "S%d", i); /* build indicator string */
X mgnum = fgnum(n, mgstr); /* get number of marriage */
X if (mgnum <= 0)
X {
X break; /* stop if no more */
X }
X if (indexes)
X {
X printf("Marriage S%d: %d\n", i, mgnum);
X }
X mhnum = fgnum(mgnum, "H"); /* are we the husband? */
X mwnum = fgnum(mgnum, "W"); /* or the wife */
X if (n != mhnum && n != mwnum)
X warning("person %d claims marriage %d, but not vice-versa",
X n, mgnum);
X if (n == mhnum)
X {
X snum = mwnum;
X sostr = "Wife";
X }
X else
X {
X snum = mhnum;
X sostr = "Husband";
X }
X if (snum > 0)
X {
X ss = bname(snum);
X printf(" %s: %s\n", sostr, ss);
X ss = fgbegend(snum);
X if (ss && *ss)
X {
X printf(" %s\n", ss);
X }
X }
X ss = fgmar(mgnum);
X if (ss && *ss)
X {
X printf(" %s\n", ss);
X }
X doiclist(mgnum,"Child","Children",-1);
X }
X for (i = 0; ; i++)
X {
X sprintf(mgstr, "GEN%d", i);
X t = bstr(n, mgstr, lbuf);
X if (t == 0)
X {
X break; /* no more strings */
X }
X if (i == 0)
X {
X printf("General:\n");
X }
X printf("%s\n", lbuf); /* print each line of GEN */
X }
X return 0; /* finished it all OK */
X}
X
X/*..........*/
X
Xdoiclist(pnum, c1, cm, xn) /* print out info about children */
Xint pnum; /* the family to deal with */
Xchar *c1; /* string to use if one child */
Xchar *cm; /* string to use if more than one child */
Xint xn; /* number of special sibling, or -1 if none */
X{
Xint i;
Xint t;
Xchar *ss;
Xint *clist;
Xint cflag = 0;
X
X t = fgclist(pnum, &clist); /* get list of kids */
X if (t == 0)
X {
X if (indexes)
X {
X printf("No %s specified\n", cm);
X }
X if (xn > 0)
X {
X warning("person %d claims parents %d but not vice-versa",
X xn, pnum);
X }
X }
X else
X {
X if (t == 1)
X {
X printf(" 1 %s:\n", c1);
X }
X else
X {
X printf(" %d %s:\n", t, cm);
X }
X for (i = 0; i < t; i++) /* for each child */
X {
X if (clist[i] == xn)
X {
X cflag++; /* note found special sibling */
X }
X if (indexes)
X {
X printf(" %s %d:", c1, i);
X }
X ss = tname(clist[i]);
X printf(" %s%s\n", (clist[i]==xn?"*":""), ss);
X ss = fgbegend(clist[i]);
X if (ss && *ss)
X {
X printf(" %s\n", ss);
X }
X }
X if (xn > 0 && cflag == 0)
X {
X warning("person %d claims parents %d but not vice-versa",
X xn, pnum);
X }
X }
X}
X
X/* end */
SHAR_EOF
if test 4224 -ne "`wc -c < 'indivs.c'`"
then
echo shar: error transmitting "'indivs.c'" '(should have been 4224 characters)'
fi
chmod +x 'indivs.c'
fi # end of overwriting check
# End of shell archive
exit 0
--
===========================================================================
| |
|UUCP: /--- !neurad--\ /---!wiretap!{root, tlr} |
|UUCP: seismo-< >---!bilbo--< |
|UUCP: \--- !umcp-cs-< \---!{root, tlr} |
| \---!tlr |
| |
|ARPA: tlr at maryland |
| |
|U.S.SNAIL: Terry L. Ridder, 401 Cherry Lane E301, Laurel, Maryland 20707 |
| |
|Ma Bell: Home: 301-490-2248 Work: 301-859-6271 Work: 301-859-6642 |
| |
===========================================================================
More information about the Comp.sources.unix
mailing list