home *** CD-ROM | disk | FTP | other *** search
/ The Best Internet Programs / BESTINTERNET.bin / latest / ged2ht20 / database.c next >
C/C++ Source or Header  |  1995-04-07  |  12KB  |  574 lines

  1. /*
  2.  * Build lineage-linked database from lines of GEDCOM file.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include "node.h"
  10. #include "database.h"
  11. #include "index.h"
  12. #include "tags.h"
  13.  
  14. /*
  15.  * Counts of various kinds of top-level records
  16.  */
  17.  
  18. int total_individuals;
  19. int total_families;
  20. int total_events;
  21. int total_sources;
  22. int total_notes;
  23. int total_repositories;
  24. int total_submitters;
  25.  
  26. /*
  27.  * Flag controlling capitalization of surnames
  28.  */
  29.  
  30. int capitalization = 1;
  31.  
  32. /*
  33.  * Arrays for each access to top-level records
  34.  */
  35.  
  36. struct individual_record **all_individuals;
  37. struct family_record **all_families;
  38.  
  39. void extract_xref(struct node *np);
  40.  
  41. /*
  42.  * Pass I: Allocate database records and attach them to the GEDCOM nodes.
  43.  */
  44.  
  45. void
  46. process_records(struct node *np)
  47. {
  48.   for( ; np != NULL; np = np->siblings) {
  49.     if(np->tag == NULL)
  50.       continue;
  51.     switch(np->tag->value) {
  52.     case INDI:
  53.       total_individuals++;
  54.       process_individual_record(np);
  55.       break;
  56.     case FAM:
  57.       total_families++;
  58.       process_family_record(np);
  59.       break;
  60.     case EVEN:
  61.       total_events++;
  62.       process_event_record(np);
  63.       break;
  64.     case NOTE:
  65.       total_notes++;
  66.       process_note_record(np);
  67.       break;
  68.     case SOUR:
  69.       total_sources++;
  70.       process_source_record(np);
  71.       break;
  72.     case REPO:
  73.       total_repositories++;
  74.       process_repository_record(np);
  75.       break;
  76.     case SUBM:
  77.       total_submitters++;
  78.       process_submitter_record(np);
  79.       break;
  80.     default:
  81.       /* Skip unrecognized records */
  82.       break;
  83.     }
  84.   }
  85. }
  86.  
  87. void
  88. process_individual_record(struct node *np)
  89. {
  90.   struct individual_record *ip;
  91.   struct note_structure *ntp;
  92.   struct xref *xp;
  93.  
  94.   if((ip = malloc(sizeof(*ip))) == NULL)
  95.     out_of_memory();
  96.   memset(ip, 0, sizeof(*ip));
  97.   np->hook = ip;
  98.   ip->xref = np->xref;
  99.   index_enter(ip->xref, ip);
  100.   for(np = np->children ; np != NULL; np = np->siblings) {
  101.     if(np->tag == NULL)
  102.       continue;
  103.     switch(np->tag->value) {
  104.     case NAME:
  105.       ip->personal_name = process_name(np);
  106.       break;
  107.     case FAMS:
  108.       xp = process_xref(np);
  109.       if(ip->fams == NULL)
  110.     ip->fams = ip->lastfams = xp;
  111.       else {
  112.     ip->lastfams->next = xp;
  113.     ip->lastfams = xp;
  114.       }
  115.       break;
  116.     case FAMC:
  117.       xp = process_xref(np);
  118.       if(ip->famc == NULL)
  119.     ip->famc = ip->lastfamc = xp;
  120.       else {
  121.     ip->lastfamc->next = xp;
  122.     ip->lastfamc = xp;
  123.       }
  124.       break;
  125.     case SOUR:
  126.       xp = process_xref(np);
  127.       if(ip->sources == NULL)
  128.     ip->sources = ip->lastsource = xp;
  129.       else {
  130.     ip->sources->next = xp;
  131.     ip->lastsource = xp;
  132.       }
  133.       break;
  134.     case REFN:
  135.       ip->refn = np->rest;
  136.       break;
  137.     case RFN:
  138.       ip->rfn = np->rest;
  139.       break;
  140.     case AFN:
  141.       ip->afn = np->rest;
  142.       break;
  143.     case NOTE:
  144.       ntp = process_note(np);
  145.       if(ip->notes == NULL)
  146.     ip->notes = ip->lastnote = ntp;
  147.       else {
  148.     ip->lastnote->next = ntp;
  149.     ip->lastnote = ntp;
  150.       }
  151.       break;
  152.     case TITL:
  153.       ip->title = np->rest;
  154.       break;
  155.     case SEX:
  156.       if(*np->rest == 'M')
  157.     ip->sex = 'M';
  158.       else if(*np->rest == 'F')
  159.     ip->sex = 'F';
  160.       break;
  161.     case CENS: case MARR: case MARB: case MARC: case MARL: case MARS:
  162.     case ENGA: case BAPM: case BARM: case BASM: case BIRT: case BLES:
  163.     case BURI: case CHR: case CHRA: case CONF: case DEAT: case EMIG:
  164.     case GRAD: case IMMI: case NATU: case ORDN: case RETI: case PROB:
  165.     case WILL: case ANUL: case DIV: case DIVF:
  166.       if(ip->events == NULL)
  167.     ip->events = ip->lastevent = process_event(np);
  168.       else {
  169.     ip->lastevent->next = process_event(np);
  170.     ip->lastevent = ip->lastevent->next;
  171.       }
  172.       break;
  173.     default:
  174.       /* Skip unrecognized substructures */
  175.       break;
  176.     }
  177.   }
  178. }
  179.  
  180. void
  181. process_family_record(struct node *np)
  182. {
  183.   struct family_record *frp;
  184.   struct note_structure *ntp;
  185.   struct xref *xp;
  186.  
  187.   if((frp = malloc(sizeof(*frp))) == NULL)
  188.     out_of_memory();
  189.   memset(frp, 0, sizeof(*frp));
  190.   np->hook = frp;
  191.   frp->xref = np->xref;
  192.   index_enter(frp->xref, frp);
  193.   for(np = np->children ; np != NULL; np = np->siblings) {
  194.     if(np->tag == NULL)
  195.       continue;
  196.     switch(np->tag->value) {
  197.     case HUSB:
  198.       frp->husband = process_xref(np);
  199.       break;
  200.     case WIFE:
  201.       frp->wife = process_xref(np);
  202.       break;
  203.     case CHIL:
  204.       xp = process_xref(np);
  205.       if(frp->children == NULL)
  206.     frp->children = frp->lastchild = xp;
  207.       else {
  208.     frp->lastchild->next = xp;
  209.     frp->lastchild = xp;
  210.       }
  211.       break;
  212.     case SOUR:
  213.       xp = process_xref(np);
  214.       if(frp->sources == NULL)
  215.     frp->sources = frp->lastsource = xp;
  216.       else {
  217.     frp->sources->next = xp;
  218.     frp->lastsource = xp;
  219.       }
  220.       break;
  221.     case REFN:
  222.       frp->refn = np->rest;
  223.       break;
  224.     case CENS: case MARR: case MARB: case MARC: case MARL: case MARS:
  225.     case ENGA: case BAPM: case BARM: case BASM: case BIRT: case BLES:
  226.     case BURI: case CHR: case CHRA: case CONF: case DEAT: case EMIG:
  227.     case GRAD: case IMMI: case NATU: case ORDN: case RETI: case PROB:
  228.     case WILL: case ANUL: case DIV: case DIVF:
  229.       if(frp->events == NULL)
  230.     frp->events = frp->lastevent = process_event(np);
  231.       else {
  232.     frp->lastevent->next = process_event(np);
  233.     frp->lastevent = frp->lastevent->next;
  234.       }
  235.       break;
  236.     case NOTE:
  237.       ntp = process_note(np);
  238.       if(frp->notes == NULL)
  239.     frp->notes = frp->lastnote = ntp;
  240.       else {
  241.     frp->lastnote->next = ntp;
  242.     frp->lastnote = ntp;
  243.       }
  244.       break;
  245.     default:
  246.       /* Skip unrecognized substructures */
  247.       break;
  248.     }
  249.   }
  250. }
  251.  
  252. void
  253. process_source_record(struct node *np)
  254. {
  255.   struct source_record *sp;
  256.   struct continuation *cp;
  257.   int cont = 0;
  258.  
  259.   if((sp = malloc(sizeof(*sp))) == NULL)
  260.     out_of_memory();
  261.   memset(sp, 0, sizeof(*sp));
  262.   np->hook = sp;
  263.   sp->xref = np->xref;
  264.   index_enter(sp->xref, sp);
  265.   sp->text = np->rest;
  266.   for(np = np->children ; np != NULL; np = np->siblings) {
  267.     if(np->tag == NULL)
  268.       continue;
  269.     switch(np->tag->value) {
  270.     case CONT:
  271.       if(cont == 0) {
  272.     cont++;
  273.     if((sp->cont = malloc(sizeof(*sp->cont))) == NULL)
  274.       out_of_memory();
  275.     cp = sp->cont;
  276.       } else {
  277.     if((cp->next = malloc(sizeof(*cp->next))) == NULL)
  278.       out_of_memory();
  279.     cp = cp->next;
  280.       }
  281.       memset(cp, 0, sizeof(*cp));
  282.       np->hook = cp;
  283.       cp->text = np->rest;
  284.       break;
  285.     }
  286.   }
  287. }
  288.  
  289. void
  290. process_event_record(struct node *np)
  291. {
  292.  
  293. }
  294.  
  295. void
  296. process_note_record(struct node *np)
  297. {
  298.  
  299. }
  300.  
  301. void
  302. process_repository_record(struct node *np)
  303. {
  304.  
  305. }
  306.  
  307. void
  308. process_submitter_record(struct node *np)
  309. {
  310.  
  311. }
  312.  
  313. struct event_structure *
  314. process_event(struct node *np)
  315. {
  316.   struct event_structure *ep;
  317.   struct place_structure *pp;
  318.  
  319.   if((ep = malloc(sizeof(*ep))) == NULL)
  320.     out_of_memory();
  321.   memset(ep, 0, sizeof(*ep));
  322.   np->hook = ep;
  323.   ep->tag = np->tag;
  324.   for(np = np->children; np != NULL; np = np->siblings) {
  325.     if(np->tag == NULL)
  326.       continue;
  327.     switch(np->tag->value) {
  328.     case DATE:
  329.       ep->date = np->rest;
  330.       break;
  331.     case PLAC:
  332.       if((pp = malloc(sizeof(*pp))) == NULL)
  333.     out_of_memory();
  334.       memset(pp, 0, sizeof(*pp));
  335.       pp->name = np->rest;
  336.       ep->place = pp;
  337.       break;
  338.     default:
  339.       break;
  340.     }
  341.   }
  342.   return(ep);
  343. }
  344.  
  345. struct note_structure *
  346. process_note(struct node *np)
  347. {
  348.   struct note_structure *ntp;
  349.   struct continuation *ntpc;
  350.   int cont = 0;
  351.  
  352.   if((ntp = malloc(sizeof(*ntp))) == NULL)
  353.     out_of_memory();
  354.   memset(ntp, 0, sizeof(*ntp));
  355.   np->hook = ntp;
  356.   ntp->text = np->rest;
  357.   for(np = np->children; np != NULL; np = np->siblings) {
  358.     if(np->tag == NULL)
  359.       continue;
  360.     switch(np->tag->value) {
  361.     case CONT:
  362.       if(cont == 0) {
  363.     cont++;
  364.     if((ntp->cont = malloc(sizeof(*ntp->cont))) == NULL)
  365.       out_of_memory();
  366.     ntpc = ntp->cont;
  367.       } else {
  368.     if((ntpc->next = malloc(sizeof(*ntpc->next))) == NULL)
  369.       out_of_memory();
  370.     ntpc = ntpc->next;
  371.       }
  372.       memset(ntpc, 0, sizeof(*ntpc));
  373.       np->hook = ntpc;
  374.       ntpc->text = np->rest;
  375.       break;
  376.     default:
  377.       break;
  378.     }
  379.   }
  380.   return(ntp);
  381. }
  382.  
  383. struct xref *
  384. process_xref(struct node *np)
  385. {
  386.   struct xref *xp;
  387.  
  388.   extract_xref(np);
  389.   if((xp = malloc(sizeof(*xp))) == NULL)
  390.     out_of_memory();
  391.   memset(xp, 0, size