コード例 #1
0
ファイル: dbverify.c プロジェクト: MarcNo/lifelines
/*============================================
 * cgn_callback -- callback for name traversal
 *  for checking for ghost names
 * Created: 2001/01/01, Perry Rapp
 *==========================================*/
static BOOLEAN
cgn_callback (TRAV_NAMES_FUNC_ARGS(key, name, newset, param))
{
    /* a name record which points at indi=key */
    RECORD indi0 = NULL;
    NODE indi = NULL;
    param=param; /* unused */

    /* bail out immediately if not INDI */
    if (key[0] != 'I') {
        report_error(ERR_NONINDINAME
                     , _("Non-indi name, key=%s, name=%s")
                     , key, name);
        return 1; /* continue traversal */
    }

    indi0 = qkey_to_irecord(key);
    indi = nztop(indi0);

    if (newset) {
        finish_and_delete_nameset();
        soundexseq = create_indiseq_sval();
    }

    append_indiseq_sval(soundexseq, strsave(key), (STRING)name, strsave(name)
                        , TRUE, TRUE); /* sure, alloc */

    if (!indi) {
        report_error(ERR_ORPHANNAME, _("Orphaned name: %s"), name);
        if (todo.fix_ghosts)
            enqueue_list(tofix, (VPTR)alloc_namerefn(name, key, ERR_ORPHANNAME));
    } else {
        NODE node;
        BOOLEAN found=FALSE;
        NODE nam, refn, sex, body, famc, fams;
        split_indi_old(indi, &nam, &refn, &sex, &body, &famc, &fams);
        for (node = nam; node; node = nsibling(node)) {
            if (!strcmp(nval(node), name))
                found=TRUE;
        }
        join_indi(indi, nam, refn, sex, body, famc, fams);
        if (!found) {
            report_error(ERR_GHOSTNAME, _("Ghost name: %s -> %s"), name, key);
            if (todo.fix_ghosts)
                enqueue_list(tofix, (VPTR)alloc_namerefn(name, key, ERR_GHOSTNAME));
        }
    }

    if (noisy)
        report_progress("Name: %s", name);

    return 1; /* continue traversal */
}
コード例 #2
0
ファイル: add.c プロジェクト: MarcNo/lifelines
/*================================================================
 * add_indi_no_cache -- Add new person to database
 *  does not insert into cache
 *  (used by import)
 * (no user interaction)
 *==============================================================*/
BOOLEAN
add_indi_no_cache (NODE indi)
{
	NODE node, name, refn, sex, body, famc, fams;
	STRING str, key;

	split_indi_old(indi, &name, &refn, &sex, &body, &famc, &fams);
	key = rmvat(nxref(indi));
	for (node = name; node; node = nsibling(node))
		add_name(nval(node), key);
	for (node = refn; node; node = nsibling(node))
		if (nval(node)) add_refn(nval(node), key);
	join_indi(indi, name, refn, sex, body, famc, fams);
	resolve_refn_links(indi);
	str = node_to_string(indi);
	store_record(key, str, strlen(str));
	stdfree(str);
	return TRUE;
}
コード例 #3
0
ファイル: nodeio.c プロジェクト: MarcNo/lifelines
/*=====================================
 * write_indi_to_file - write node tree into GEDCOM
 * (no user interaction)
 *===================================*/
void
write_indi_to_file (NODE indi, CNSTRING file)
{
	FILE *fp;
	XLAT ttmo = transl_get_predefined_xlat(MINED);
	NODE name, refn, sex, body, famc, fams;
	
	ASSERT(fp = fopen(file, LLWRITETEXT));
	prefix_file(fp, ttmo);

	split_indi_old(indi, &name, &refn, &sex, &body, &famc, &fams);
	write_nodes(0, fp, ttmo, indi, TRUE, TRUE, TRUE);
	write_nodes(1, fp, ttmo, name, TRUE, TRUE, TRUE);
	write_nodes(1, fp, ttmo, refn, TRUE, TRUE, TRUE);
	write_nodes(1, fp, ttmo, sex,   TRUE, TRUE, TRUE);
	write_nodes(1, fp, ttmo, body , TRUE, TRUE, TRUE);
	write_nodes(1, fp, ttmo, famc,  TRUE, TRUE, TRUE);
	write_nodes(1, fp, ttmo, fams,  TRUE, TRUE, TRUE);
	fclose(fp);
	join_indi(indi, name, refn, sex, body, famc, fams);
}
コード例 #4
0
ファイル: add.c プロジェクト: MarcNo/lifelines
/*==========================================================
 * add_new_indi_to_db -- Add newly created person to database
 * (no user interaction)
 * creates record & adds to cache
 *========================================================*/
static void
add_new_indi_to_db (RECORD indi0)
{
	NODE name, refn, sex, body, dumb, node;
	char key[MAXKEYWIDTH]="";
	INT keynum=0;
	NODE indi = nztop(indi0);

	split_indi_old(indi, &name, &refn, &sex, &body, &dumb, &dumb);
	keynum = getixrefnum();
	sprintf(key, "I%ld", keynum);
	init_new_record(indi0, key);
	for (node = name; node; node = nsibling(node)) {
		add_name(nval(node), key);
	}
	for (node = refn; node; node = nsibling(node)) {
		if (nval(node))
			add_refn(nval(node), key);
	}
	join_indi(indi, name, refn, sex, body, NULL, NULL);
	resolve_refn_links(indi);
	indi_to_dbase(indi);
	add_new_indi_to_cache(indi0);
}
コード例 #5
0
ファイル: dbverify.c プロジェクト: MarcNo/lifelines
/*=====================================
 * process_indi -- process indi record
 *  checking in pass 1, fixing in pass 2
 *===================================*/
static void
process_indi (RECORD rec)
{
    NODE indi0, indi1;
    NODE name1, refn1, sex1, body1, famc1, fams1;
    NODE node1;
    BOOLEAN altered=FALSE;
    BOOLEAN needfix=FALSE;
    CNSTRING key = nzkey(rec);

    indi0 = nztop(rec);
    if (todo.pass==1) {
        indi1 = indi0;
    } else {
        indi1 = copy_node_subtree(indi0);
    }
    split_indi_old(indi1, &name1, &refn1, &sex1, &body1, &famc1, &fams1);

    if (todo.pass == 1) {
        /* check names */
        for (node1 = name1; node1; node1 = nsibling(node1)) {
            STRING name=nval(node1);
            if (!valid_name(name)) {
                report_error(ERR_BADNAME, _("Bad name for individual %s: %s"), key, name);
            } else {
                /* TO DO: verify that name is in db */
            }
        }
        /* check refns */
        for (node1 = refn1; node1; node1 = nsibling(node1)) {
            /* STRING refn=nval(node1); */
            /* TO DO: verify that refn is in db */
        }
    }

    /* check parents */
    for (node1 = famc1; node1; node1 = nsibling(node1)) {
        STRING famkey=rmvat(nval(node1));
        NODE fam2 = qkey_to_fam(famkey);
        if (!fam2) {
            if (todo.pass == 1) {
                report_error(ERR_BADFAMREF, _("Bad family reference (%s) individual %s"), famkey, key);
            }
        } else {
            /* look for indi1 (key) in fam2's children */
            if (!find_xref(key, fam2, "CHIL", NULL)) {
                if (todo.pass == 1) {
                    report_error(ERR_MISSINGCHILD, _("Missing child (%s) in family (%s)"), key, famkey);
                    needfix=TRUE;
                } else {
                    if (fix_bad_pointer(key, rec, node1)) {
                        report_fix(ERR_MISSINGCHILD, _("Fixed missing child (%s) in family (%s)"), key, famkey);
                        altered=TRUE;
                    }
                }
            }
        }
    }

    /* check spouses */
    for (node1 = fams1; node1; node1 = nsibling(node1)) {
        STRING famkey=rmvat(nval(node1));
        NODE fam2 = qkey_to_fam(famkey);
        if (!fam2) {
            if (todo.pass == 1) {
                report_error(ERR_BADFAMREF, _("Bad family reference (%s) individual %s"), famkey, key);
            }
        } else {
            /* look for indi1 (key) in fam2's spouses */
            if (!find_xref(key, fam2, "HUSB", "WIFE")) {
                if (todo.pass == 1) {
                    report_error(ERR_MISSINGSPOUSE, _("Missing spouse (%s) in family (%s)"), key, famkey);
                    needfix=TRUE;
                } else {
                    if (fix_bad_pointer(key, rec, node1)) {
                        report_fix(ERR_MISSINGSPOUSE, _("Fixed missing spouse (%s) in family (%s)"), key, famkey);
                        altered=TRUE;
                    }
                }
            }
        }
    }

    join_indi(indi1, name1, refn1, sex1, body1, famc1, fams1);
    if (altered) {
        /* must normalize, as some lineage references may have been
        altered to non-lineage tags to fix broken pointers */
        normalize_indi(indi1);

        /* write to database */
        replace_indi(indi0, indi1);

    } else if (needfix) {
        enqueue_list(tofix, strsave(key));
    }
}
コード例 #6
0
/*===================================
 * valid_indi_tree -- Validate person tree
 *  indi1:  [IN]  person to validate
 *  pmsg:   [OUT] error message, if any
 *  orig:   [IN]  person to match - may be NULL
 * rtn: FALSE for bad
 * Should be replaced by valid_indi(RECORD,...) ?
 *=================================*/
BOOLEAN
valid_indi_tree (NODE indi1, STRING *pmsg, NODE orig)
{
	NODE name1, refn1, sex1, body1, famc1, fams1, node;
	NODE name0, refn0, sex0, body0, famc0, fams0;
	INT isex, num;
	STRING *keys, ukey;

	if (!indi1) {
		*pmsg = _(qSbademp);
  		return FALSE;
	}
	if (nestr("INDI", ntag(indi1))) {
		*pmsg = _(qSbadin0);
		return FALSE;
	}
	if (nsibling(indi1)) {
		*pmsg = _(qSbadmul);
		return FALSE;
	}
	split_indi_old(indi1, &name1, &refn1, &sex1, &body1, &famc1, &fams1);
	if (getlloptint("RequireNames", 0) && !name1) {
		*pmsg = _("This person record does not have a name line.");
		goto bad2;
	}
	for (node = name1; node; node = nsibling(node)) {
		if (!valid_name(nval(node))) {
			*pmsg = _(qSbadenm);
			goto bad2;
		}
	}
	name0 = refn0 = sex0 = body0 = famc0 = fams0 = NULL;
	if (orig)
		split_indi_old(orig, &name0, &refn0, &sex0, &body0, &famc0,
		    &fams0);
	if (orig && !iso_nodes(indi1, orig, FALSE, FALSE)) {
		*pmsg = _(qSbadind); 
		goto bad1;
	}
	if (!iso_nodes(famc1, famc0, FALSE, TRUE)) {
		*pmsg = _(qSbadfmc);
		goto bad1;
	}
	if (!iso_nodes(fams1, fams0, FALSE, TRUE)) {
		*pmsg = _(qSbadfms); 
		goto bad1;
	}
	isex = val_to_sex(sex0);
	if (!fams0) isex = SEX_UNKNOWN;
	if (isex != SEX_UNKNOWN && isex != val_to_sex(sex1)) {
		*pmsg = _(qSbadparsex);
		goto bad1;
	}
	ukey = (refn1 ? nval(refn1) : NULL);
	get_refns(ukey, &num, &keys, 'I');
	if (num > 1 || (num == 1 && (!orig ||
	    nestr(keys[0], rmvat(nxref(indi1)))))) {
		*pmsg = _(qSbadirefn);
		goto bad1;
	}
	if (orig)
		join_indi(orig, name0, refn0, sex0, body0, famc0, fams0);
	join_indi(indi1, name1, refn1, sex1, body1, famc1, fams1);
	return TRUE;
bad1:
	if (orig)
		join_indi(orig, name0, refn0, sex0, body0, famc0, fams0);
bad2:
	join_indi(indi1, name1, refn1, sex1, body1, famc1, fams1);
	return FALSE;
}