home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best Internet Programs
/
BESTINTERNET.bin
/
latest
/
ged2ht20
/
database.c
next >
Wrap
C/C++ Source or Header
|
1995-04-07
|
12KB
|
574 lines
/*
* Build lineage-linked database from lines of GEDCOM file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "node.h"
#include "database.h"
#include "index.h"
#include "tags.h"
/*
* Counts of various kinds of top-level records
*/
int total_individuals;
int total_families;
int total_events;
int total_sources;
int total_notes;
int total_repositories;
int total_submitters;
/*
* Flag controlling capitalization of surnames
*/
int capitalization = 1;
/*
* Arrays for each access to top-level records
*/
struct individual_record **all_individuals;
struct family_record **all_families;
void extract_xref(struct node *np);
/*
* Pass I: Allocate database records and attach them to the GEDCOM nodes.
*/
void
process_records(struct node *np)
{
for( ; np != NULL; np = np->siblings) {
if(np->tag == NULL)
continue;
switch(np->tag->value) {
case INDI:
total_individuals++;
process_individual_record(np);
break;
case FAM:
total_families++;
process_family_record(np);
break;
case EVEN:
total_events++;
process_event_record(np);
break;
case NOTE:
total_notes++;
process_note_record(np);
break;
case SOUR:
total_sources++;
process_source_record(np);
break;
case REPO:
total_repositories++;
process_repository_record(np);
break;
case SUBM:
total_submitters++;
process_submitter_record(np);
break;
default:
/* Skip unrecognized records */
break;
}
}
}
void
process_individual_record(struct node *np)
{
struct individual_record *ip;
struct note_structure *ntp;
struct xref *xp;
if((ip = malloc(sizeof(*ip))) == NULL)
out_of_memory();
memset(ip, 0, sizeof(*ip));
np->hook = ip;
ip->xref = np->xref;
index_enter(ip->xref, ip);
for(np = np->children ; np != NULL; np = np->siblings) {
if(np->tag == NULL)
continue;
switch(np->tag->value) {
case NAME:
ip->personal_name = process_name(np);
break;
case FAMS:
xp = process_xref(np);
if(ip->fams == NULL)
ip->fams = ip->lastfams = xp;
else {
ip->lastfams->next = xp;
ip->lastfams = xp;
}
break;
case FAMC:
xp = process_xref(np);
if(ip->famc == NULL)
ip->famc = ip->lastfamc = xp;
else {
ip->lastfamc->next = xp;
ip->lastfamc = xp;
}
break;
case SOUR:
xp = process_xref(np);
if(ip->sources == NULL)
ip->sources = ip->lastsource = xp;
else {
ip->sources->next = xp;
ip->lastsource = xp;
}
break;
case REFN:
ip->refn = np->rest;
break;
case RFN:
ip->rfn = np->rest;
break;
case AFN:
ip->afn = np->rest;
break;
case NOTE:
ntp = process_note(np);
if(ip->notes == NULL)
ip->notes = ip->lastnote = ntp;
else {
ip->lastnote->next = ntp;
ip->lastnote = ntp;
}
break;
case TITL:
ip->title = np->rest;
break;
case SEX:
if(*np->rest == 'M')
ip->sex = 'M';
else if(*np->rest == 'F')
ip->sex = 'F';
break;
case CENS: case MARR: case MARB: case MARC: case MARL: case MARS:
case ENGA: case BAPM: case BARM: case BASM: case BIRT: case BLES:
case BURI: case CHR: case CHRA: case CONF: case DEAT: case EMIG:
case GRAD: case IMMI: case NATU: case ORDN: case RETI: case PROB:
case WILL: case ANUL: case DIV: case DIVF:
if(ip->events == NULL)
ip->events = ip->lastevent = process_event(np);
else {
ip->lastevent->next = process_event(np);
ip->lastevent = ip->lastevent->next;
}
break;
default:
/* Skip unrecognized substructures */
break;
}
}
}
void
process_family_record(struct node *np)
{
struct family_record *frp;
struct note_structure *ntp;
struct xref *xp;
if((frp = malloc(sizeof(*frp))) == NULL)
out_of_memory();
memset(frp, 0, sizeof(*frp));
np->hook = frp;
frp->xref = np->xref;
index_enter(frp->xref, frp);
for(np = np->children ; np != NULL; np = np->siblings) {
if(np->tag == NULL)
continue;
switch(np->tag->value) {
case HUSB:
frp->husband = process_xref(np);
break;
case WIFE:
frp->wife = process_xref(np);
break;
case CHIL:
xp = process_xref(np);
if(frp->children == NULL)
frp->children = frp->lastchild = xp;
else {
frp->lastchild->next = xp;
frp->lastchild = xp;
}
break;
case SOUR:
xp = process_xref(np);
if(frp->sources == NULL)
frp->sources = frp->lastsource = xp;
else {
frp->sources->next = xp;
frp->lastsource = xp;
}
break;
case REFN:
frp->refn = np->rest;
break;
case CENS: case MARR: case MARB: case MARC: case MARL: case MARS:
case ENGA: case BAPM: case BARM: case BASM: case BIRT: case BLES:
case BURI: case CHR: case CHRA: case CONF: case DEAT: case EMIG:
case GRAD: case IMMI: case NATU: case ORDN: case RETI: case PROB:
case WILL: case ANUL: case DIV: case DIVF:
if(frp->events == NULL)
frp->events = frp->lastevent = process_event(np);
else {
frp->lastevent->next = process_event(np);
frp->lastevent = frp->lastevent->next;
}
break;
case NOTE:
ntp = process_note(np);
if(frp->notes == NULL)
frp->notes = frp->lastnote = ntp;
else {
frp->lastnote->next = ntp;
frp->lastnote = ntp;
}
break;
default:
/* Skip unrecognized substructures */
break;
}
}
}
void
process_source_record(struct node *np)
{
struct source_record *sp;
struct continuation *cp;
int cont = 0;
if((sp = malloc(sizeof(*sp))) == NULL)
out_of_memory();
memset(sp, 0, sizeof(*sp));
np->hook = sp;
sp->xref = np->xref;
index_enter(sp->xref, sp);
sp->text = np->rest;
for(np = np->children ; np != NULL; np = np->siblings) {
if(np->tag == NULL)
continue;
switch(np->tag->value) {
case CONT:
if(cont == 0) {
cont++;
if((sp->cont = malloc(sizeof(*sp->cont))) == NULL)
out_of_memory();
cp = sp->cont;
} else {
if((cp->next = malloc(sizeof(*cp->next))) == NULL)
out_of_memory();
cp = cp->next;
}
memset(cp, 0, sizeof(*cp));
np->hook = cp;
cp->text = np->rest;
break;
}
}
}
void
process_event_record(struct node *np)
{
}
void
process_note_record(struct node *np)
{
}
void
process_repository_record(struct node *np)
{
}
void
process_submitter_record(struct node *np)
{
}
struct event_structure *
process_event(struct node *np)
{
struct event_structure *ep;
struct place_structure *pp;
if((ep = malloc(sizeof(*ep))) == NULL)
out_of_memory();
memset(ep, 0, sizeof(*ep));
np->hook = ep;
ep->tag = np->tag;
for(np = np->children; np != NULL; np = np->siblings) {
if(np->tag == NULL)
continue;
switch(np->tag->value) {
case DATE:
ep->date = np->rest;
break;
case PLAC:
if((pp = malloc(sizeof(*pp))) == NULL)
out_of_memory();
memset(pp, 0, sizeof(*pp));
pp->name = np->rest;
ep->place = pp;
break;
default:
break;
}
}
return(ep);
}
struct note_structure *
process_note(struct node *np)
{
struct note_structure *ntp;
struct continuation *ntpc;
int cont = 0;
if((ntp = malloc(sizeof(*ntp))) == NULL)
out_of_memory();
memset(ntp, 0, sizeof(*ntp));
np->hook = ntp;
ntp->text = np->rest;
for(np = np->children; np != NULL; np = np->siblings) {
if(np->tag == NULL)
continue;
switch(np->tag->value) {
case CONT:
if(cont == 0) {
cont++;
if((ntp->cont = malloc(sizeof(*ntp->cont))) == NULL)
out_of_memory();
ntpc = ntp->cont;
} else {
if((ntpc->next = malloc(sizeof(*ntpc->next))) == NULL)
out_of_memory();
ntpc = ntpc->next;
}
memset(ntpc, 0, sizeof(*ntpc));
np->hook = ntpc;
ntpc->text = np->rest;
break;
default:
break;
}
}
return(ntp);
}
struct xref *
process_xref(struct node *np)
{
struct xref *xp;
extract_xref(np);
if((xp = malloc(sizeof(*xp))) == NULL)
out_of_memory();
memset(xp, 0, size