예제 #1
0
/*===============================
 * valid_fam_tree -- Validate FAM tree
 *  fam1,  [IN]  family to validate
 *  pmsg:  [OUT] error message, if any
 *  fam0:  [IN]  family to match - may be NULL
 * Should be replaced by valid_fam(RECORD,...) ?
 *=============================*/
BOOLEAN
valid_fam_tree (NODE fam1, STRING *pmsg, NODE fam0)
{
	NODE refn0, husb0, wife0, chil0, body0;
	NODE refn1, husb1, wife1, chil1, body1;

	if (!fam1) {
		*pmsg = _(qSbademp);
  		return FALSE;
	}
	if (nestr("FAM", ntag(fam1))) {
		*pmsg = _(qSbadfm0);
		return FALSE;
	}
	if (nsibling(fam1)) {
		*pmsg = _(qSbadmul);
		return FALSE;
	}

	refn0 = husb0 = wife0 = chil0 = body0 = NULL;
	if (fam0)
		split_fam(fam0, &refn0, &husb0, &wife0, &chil0, &body0);
	split_fam(fam1, &refn1, &husb1, &wife1, &chil1, &body1);
	
	if (fam0 && !iso_nodes(fam1, fam0, FALSE, TRUE)) {
		*pmsg = _(qSbadfam); 
		goto bad3;
	}
	if (!iso_nodes(husb1, husb0, FALSE, TRUE)) {
		*pmsg = _(qSbadhsb);
		goto bad3;
	}
	if (!iso_nodes(wife1, wife0, FALSE, TRUE)) {
		*pmsg = _(qSbadwif);
		goto bad3;
	}
	if (!iso_nodes(chil1, chil0, FALSE, TRUE)) {
		*pmsg = _(qSbadchl);
		goto bad3;
	}
	if (fam0)
		join_fam(fam0, refn0, husb0, wife0, chil0, body0);
	join_fam(fam1, refn1, husb1, wife1, chil1, body1);
	return TRUE;
bad3:
	if (fam0)
		join_fam(fam0, refn0, husb0, wife0, chil0, body0);
	join_fam(fam1, refn1, husb1, wife1, chil1, body1);
	return FALSE;
}
예제 #2
0
파일: nodeutls.c 프로젝트: MarcNo/lifelines
/*======================================================================
 * unique_nodes -- Remove duplicates from list of nodes -- original list
 *   is modified
 *====================================================================*/
NODE
unique_nodes (NODE node,
              BOOLEAN kids)     /* children matter */
{
	NODE node0 = node, prev, this, next;

	if (!node) return NULL;
	while (node) {
		prev = node;
		this = nsibling(node);
		while (this) {
			if (iso_nodes(node, this, kids, FALSE)) {
				nsibling(prev) = next = nsibling(this);
				nsibling(this) = NULL;
				free_nodes(this);
				this = next;
			} else {
				prev = this;
				this = nsibling(this);
			}
		}
		node = nsibling(node);
	}
	return node0;
}
예제 #3
0
파일: nodeutls.c 프로젝트: MarcNo/lifelines
/*========================================================================
 * difference_nodes -- Return difference of two node lists -- all in node1
 *   that are not in node2
 * UNUSED CODE
 *======================================================================*/
NODE
difference_nodes (NODE node1,
                  NODE node2,
                  BOOLEAN kids) /* children matter */
{
	NODE prev1, next1, curs1, curs2;
	node1 = copy_nodes(node1, TRUE, TRUE);
	prev1 = NULL;
	curs1 = node1;
	while (curs1) {
		curs2 = node2;
		while (curs2 && !iso_nodes(curs1, curs2, kids, FALSE))
			curs2 = nsibling(curs2);
		if (curs2) {
			next1 = nsibling(curs1);
			nsibling(curs1) = NULL;
			free_nodes(curs1);
			if (!prev1)
				node1 = next1;
			else
				nsibling(prev1) = next1;
			curs1 = next1;
		} else {
			prev1 = curs1;
			curs1 = nsibling(curs1);
		}
	}
	return node1;
}
예제 #4
0
파일: nodeutls.c 프로젝트: MarcNo/lifelines
/*=========================================================
 * intersect_nodes -- Return intersection of two node trees
 * UNUSED CODE
 *=======================================================*/
NODE
intersect_nodes (NODE node1,
                 NODE node2,
                 BOOLEAN kids)  /* children matter */
{
	NODE prev1, curs1, next1, prev2, curs2, next2;
	NODE node3, curs3;

	if (!node1 || !node2) return NULL;
	node1 = copy_nodes(node1, TRUE, TRUE);
	node2 = copy_nodes(node2, TRUE, TRUE);
	node3 = curs3 = NULL;

	prev1 = NULL;
	curs1 = node1;
	while (curs1) {
		prev2 = NULL;
		curs2 = node2;
		while (curs2 && !iso_nodes(curs1, curs2, kids, FALSE)) {
			prev2 = curs2;
			curs2 = nsibling(curs2);
		}
		if (curs2) {
			next2 = nsibling(curs2);
			nsibling(curs2) = NULL;

			if (node3)
				curs3 = nsibling(curs3) = curs2;
			else
				node3 = curs3 = curs2;
			if (prev2)
				nsibling(prev2) = next2;
			else
				node2 = next2;

			next1 = nsibling(curs1);
			nsibling(curs1) = NULL;
			free_nodes(curs1);
			if (prev1)
				nsibling(prev1) = next1;
			else
				node1 = next1;
			curs1 = next1;

		} else {
			prev1 = curs1;
			curs1 = nsibling(curs1);
		}
	}
	free_nodes(node1);
	free_nodes(node2);
	return node3;
}
예제 #5
0
파일: nodeutls.c 프로젝트: MarcNo/lifelines
/*==============================================
 * union_nodes -- Return union of two node trees
 *============================================*/
NODE
union_nodes (NODE node1,
             NODE node2,
             BOOLEAN kids,      /* children matter */
             BOOLEAN copy)      /* copy operands first */
{
	NODE curs1, next1, prev1, curs2, prev2;

	if (copy) node1 = copy_nodes(node1, TRUE, TRUE);
	if (copy) node2 = copy_nodes(node2, TRUE, TRUE);
	prev2 = NULL;
	curs2 = node2;
	while (curs2) {
		prev1 = NULL;
		curs1 = node1;
		while (curs1 && !iso_nodes(curs1, curs2, kids, FALSE)) {
			prev1 = curs1;
			curs1 = nsibling(curs1);
		}
		if (curs1) {
			next1 = nsibling(curs1);
			nsibling(curs1) = NULL;
			free_nodes(curs1);
			if (prev1)
				nsibling(prev1) = next1;
			else
				node1 = next1;
		}
		prev2 = curs2;
		curs2 = nsibling(curs2);
	}
	if (prev2) {
		nsibling(prev2) = node1;
		return node2;
	}
	return node1;
}
예제 #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;
}