Exemple #1
0
/*===============================================+
 * llrpt_difference -- Create difference of two INDISEQs
 * usage: difference(SET, SET) -> SET
 *==============================================*/
PVALUE
llrpt_difference (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	PNODE arg1 = builtin_args(node);
	PNODE arg2 = inext(arg1);
	INDISEQ op2=0, op1=0;
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	PVALUE val2=0;
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonsetx, "difference", "1");
		return NULL;
	}
	/* NULL indiseqs are possible, because of getindiset */
	op1 = pvalue_to_seq(val1);
	val2 = eval_and_coerce(PSET, arg2, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg2, val2, nonsetx, "difference", "2");
		return NULL;
	}
	op2 = pvalue_to_seq(val2);
	/* do actual difference */
	op2 = difference_indiseq(op1, op2);
	set_pvalue_seq(val1, op2);
	/* delay to last minute lest it is a temp owning seq,
	eg, difference(ancestorset(i),ancestorset(j)) */
	delete_pvalue(val2);
	return val1;
}
Exemple #2
0
/*======================================+
 * llrpt_newfile -- Switch output to new file
 * usage: newfile(STRING, BOOL) -> VOID
 *=====================================*/
PVALUE
llrpt_newfile (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	PNODE argvar = builtin_args(node);
	BOOLEAN aflag=FALSE;
	STRING name=0;
	PVALUE val = eval_and_coerce(PSTRING, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonstrx, "newfile", "1");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	name = pvalue_to_string(val);
	if (!name || !name[0]) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, "1st arg to newfile must be a nonempty string.");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	strupdate(&outfilename, name);
	delete_pvalue_ptr(&val);
	val = eval_and_coerce(PBOOL, argvar=inext(argvar), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonboox, "newfile", "2");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	aflag = pvalue_to_bool(val);
	delete_pvalue_ptr(&val);
	if (!set_output_file(outfilename, aflag)) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, NULL, "Failed to open output file: %s", outfilename);
	}
	return NULL;
}
Exemple #3
0
/*=====================================
 * llrpt_createnode -- Create GEDCOM node
 * usage: createnode(STRING, STRING) -> NODE
 * args: (tag, value)
 *===================================*/
PVALUE
llrpt_createnode (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	PNODE arg = iargs(node);
	NODE newnode=0;
	NODE prnt=NULL; /* parent node for new node */
	STRING xref=NULL; /* xref for new node */
	PVALUE val1=NULL, val2=NULL;
	STRING str1=NULL; /* 1st arg, which is tag for new node */
	STRING str2=NULL; /* 2nd arg, which is value for new node */
	val1 = eval_and_coerce(PSTRING, arg, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg, val1, nonstrx, "createnode", "1");
		delete_pvalue(val1);
		return NULL;
	}
	/* 1st arg is tag for new node */
	str1 = pvalue_to_string(val1);
	val2 = eval_and_coerce(PSTRING, arg=inext(arg), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg, val2, nonstrx, "createnode", "2");
		delete_pvalue(val2);
		return NULL;
	}
	/* 2nd arg is value for new node */
	str2 = pvalue_to_string(val2);
	newnode = create_temp_node(xref, str1, str2, prnt);
	return create_pvalue_from_node(newnode);
}
Exemple #4
0
/*========================================+
 * llrpt_row -- Position output to start of row
 * usage: row(INT) -> VOID
 *=======================================*/
PVALUE
llrpt_row (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INT row=0;
	PNODE argvar = builtin_args(node);
	PVALUE val = eval_and_coerce(PINT, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonint1, "row");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	*eflg = TRUE;
	row = pvalue_to_int(val);
	delete_pvalue_ptr(&val);
	if (outputmode != PAGEMODE) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, "row only valid in page mode");
		return NULL;
	}
	if (row < 1 || row > __rows) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badarg1, "row");
		return NULL;
	}
	*eflg = FALSE;
	currow = row;
	curcol = 1;
	return NULL;
}
Exemple #5
0
/*============================================
 * llrpt_detachnode -- Remove node from GEDCOM tree
 * usage: detachnode(NODE) -> VOID
 * (This is the historic deletenode)
 *==========================================*/
PVALUE
llrpt_detachnode (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	PNODE arg = iargs(node);
	NODE dead, prnt;
	PVALUE val = eval_and_coerce(PGNODE, arg, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg, val, nonnod1, "detachnode");
		delete_pvalue(val);
		return NULL;
	}
	dead = pvalue_to_node(val);
	if ((prnt = nparent(dead))) {
		NODE prev = NULL, next;
		NODE curs = nchild(prnt);
		while (curs && curs != dead) {
			prev = curs;
			curs = nsibling(curs);
		}
		ASSERT(curs); /* else broken tree: dead was not child of its parent */
		next = nsibling(dead);
		if (prev == NULL) 
			nchild(prnt) = next;
		else
			nsibling(prev) = next;
	}
	/* unparent node, but ensure its locking is only releative to new parent */
	dolock_node_in_cache(dead, FALSE);
	nparent(dead) = NULL;
	dolock_node_in_cache(dead, TRUE);
	nsibling(dead) = NULL;
	/* we don't actually delete the node, garbage collection must get it */
	return NULL;
}
Exemple #6
0
/*===========================================+
 * llrpt_deletefromset -- Remove person from INDISEQ
 * usage: deletefromset(SET, INDI, BOOL) -> VOID
 *==========================================*/
PVALUE
llrpt_deletefromset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	NODE indi;
	STRING key=0;
	BOOLEAN all, rc;
	INDISEQ seq;
	PNODE arg1 = builtin_args(node), arg2 = inext(arg1),
	    arg3 = inext(arg2);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	PVALUE val3=0;
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonsetx, "deletefromset", "1");
		goto dfs_exit;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	indi = eval_indi(arg2, stab, eflg, NULL);
	if (*eflg) {
		prog_var_error(node, stab, arg2, NULL, nonindx, "deletefromset", "2");
		goto dfs_exit;
	}
	if (!indi) goto dfs_exit;
	*eflg = TRUE;
	if (!(key = strsave(rmvat(nxref(indi))))) {
		prog_error(node, "major error in deletefromset.");
		goto dfs_exit;
	}
	*eflg = FALSE;
	val3 = eval_and_coerce(PBOOL, arg3, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg2, NULL, nonboox, "deletefromset", "3");
		goto dfs_exit;
	}
	all = pvalue_to_bool(val3);
	delete_pvalue(val3);
	do {
		rc = delete_indiseq(seq, key, NULL, 0);
	} while (rc && all);
dfs_exit:
	/* delay delete of val1 to last minute lest it is a temp owning seq,
	    eg, deletefromset(ancestorset(i),j) */
	if (val1) delete_pvalue(val1);
	if (key) strfree(&key);
	return NULL;
}
Exemple #7
0
/*========================================+
 * llrpt_pagemode -- Switch output to page mode
 * usage: pagemode(INT, INT) -> VOID
 *======================================*/
PVALUE
llrpt_pagemode (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INT cols=0, rows=0;
	PNODE argvar = builtin_args(node);
	PVALUE val = eval_and_coerce(PINT, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonintx, "pagemode", "1");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	rows = pvalue_to_int(val);
	delete_pvalue_ptr(&val);
	val = eval_and_coerce(PINT, argvar=inext(argvar), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonintx, "pagemode", "2");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	cols = pvalue_to_int(val);
	delete_pvalue_ptr(&val);
	*eflg = TRUE;
	if (!(cols >= 1 && cols <= MAXCOLS)) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badargx, "pagemode", "1");
		return NULL;
	}
	if (!(rows >= 1 && rows <= MAXROWS)) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badargx, "pagemode", "2");
		return NULL;
	}
	*eflg = FALSE;
	outputmode = PAGEMODE;
	__rows = rows;
	__cols = cols;
	if (pagebuffer) stdfree(pagebuffer);
	pagebuffer = (STRING) stdalloc(__rows*__cols);
	memset(pagebuffer, ' ', __rows*__cols);
	return NULL;
}
Exemple #8
0
/*===============================================+
 * llrpt_pos -- Position page output to row and column
 * usage: pos(INT, INT) -> VOID
 *==============================================*/
PVALUE
llrpt_pos (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INT col=0, row=0;
	PNODE argvar = builtin_args(node);
	PVALUE val = eval_and_coerce(PINT, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonintx, "pos", "1");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	row = pvalue_to_int(val);
	if (row < 1 || row > __rows) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badargx, "pos", "1");
		return NULL;
	}
	delete_pvalue_ptr(&val);
	val = eval_and_coerce(PINT, argvar=inext(argvar), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonintx, "pos", "2");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	col = pvalue_to_int(val);
	if (col < 1 || col > __cols) {
		*eflg = TRUE;
		prog_var_error(node, stab, argvar, val, badargx, "pos", "2");
		return NULL;
	}
	delete_pvalue_ptr(&val);
	if (outputmode != PAGEMODE) {
		*eflg = TRUE;
		prog_var_error(node, stab, NULL, val, "pos only valid in page mode");
		return NULL;
	}
	currow = row;
	curcol = col;
	return NULL;
}
Exemple #9
0
/*====================================================+
 * llrpt_descendentset -- Create descendent set of an INDISEQ
 * usage: descendantset(SET) -> SET
 *===================================================*/
PVALUE
llrpt_descendentset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "descendentset");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	seq = descendent_indiseq(seq);
	set_pvalue_seq(val1, seq);
	return val1;
}
Exemple #10
0
/*==========================================+
 * llrpt_childset -- Create child set of an INDISEQ
 * usage: childset(SET) -> SET
 *=========================================*/
PVALUE
llrpt_childset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "childset");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	/* do actual construction of child set */
	seq = child_indiseq(seq);
	set_pvalue_seq(val1, seq);
	return val1;
}
Exemple #11
0
/*=========================================+
 * llrpt_uniqueset -- Eliminate dupes from INDISEQ
 * usage: uniqueset(SET) -> VOID
 *========================================*/
PVALUE
llrpt_uniqueset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "uniqueset");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	unique_indiseq(seq);
	/* delay to last minute lest it is a temp owning seq,
	eg, uniqueset(ancestorset(i) */
	delete_pvalue(val1);
	return NULL;
}
Exemple #12
0
/*===================================================+
 * llrpt_gengedcomstrong -- Generate GEDCOM output from an INDISEQ
 * usage: gengedcom(SET) -> VOID
 * Perry 2000/11/03
 *==================================================*/
PVALUE
llrpt_gengedcomstrong (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "gengedcomstrong");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	gen_gedcom(seq, GENGEDCOM_STRONG_DUMP, eflg);
	/* delay to last minute lest it is a temp owning seq,
	eg, gengedcom(ancestorset(i)) */
	delete_pvalue(val1);
	return NULL;
}
Exemple #13
0
/*=========================================+
 * llrpt_parentset -- Create parent set of INDISEQ
 * usage: parentset(SET) -> SET
 *========================================*/
PVALUE
llrpt_parentset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "parentset");
		return NULL;
	}
	/* NULL indiseqs are possible, because of getindiset */
	seq = pvalue_to_seq(val1);
	/* do actual construction of parent set */
	seq = parent_indiseq(seq);
	set_pvalue_seq(val1, seq);
	return val1;
}
Exemple #14
0
/*===================================
 * llrpt_valuesort -- Sort INDISEQ by value
 * usage: valuesort(SET) -> VOID
 *=================================*/
PVALUE
llrpt_valuesort (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INDISEQ seq;
	PNODE arg1 = builtin_args(node);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonset1, "valuesort");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	valuesort_indiseq(seq,eflg);
	if (*eflg) {
		prog_error(node, _("missing or incorrect value for sort"));
		return NULL;
	}
	/* delay to last minute lest it is a temp owning seq,
	eg, valuesort(ancestorset(i) */
	delete_pvalue(val1);
	return NULL;
}
Exemple #15
0
/*==================================+
 * llrpt_addtoset -- Add person to INDISEQ
 * usage: addtoset(SET, INDI, ANY) -> VOID
 *=================================*/
PVALUE
llrpt_addtoset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	NODE indi=0;
	STRING key=0;
	INDISEQ seq=0;
	PNODE arg1 = builtin_args(node), arg2 = inext(arg1),
	    arg3 = inext(arg2);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	PVALUE val2=0;
	if (*eflg) {
		prog_var_error(node, stab, arg1, val1, nonsetx, "addtoset", "1");
		return NULL;
	}
	ASSERT(seq = pvalue_to_seq(val1));
	indi = eval_indi(arg2, stab, eflg, NULL);
	if (*eflg) {
		prog_var_error(node, stab, arg2, NULL, nonindx, "addtoset","2");
		goto ats_exit;
	}
	if (!indi) goto ats_exit;
	*eflg = TRUE;
	if (!(key = strsave(rmvat(nxref(indi))))) {
		prog_error(node, "major error in addtoset.");
		goto ats_exit;
	}
	*eflg = FALSE;
	val2 = evaluate(arg3, stab, eflg);
	if (*eflg) {
		prog_error(node, "3rd arg to addtoset is in error.");
		goto ats_exit;
	}
	append_indiseq_pval(seq, key, NULL, val2, FALSE);
ats_exit:
	if (key) strfree(&key); /* append made its own copy */
	/* delay to last minute val1 cleanup lest it is a temp owning seq,
	    eg, addtoset(ancestorset(i),j) */
	if (val1) delete_pvalue(val1);
	return NULL;
}
Exemple #16
0
/*==================================+
 * llrpt_col -- Position output to column
 * usage: col(INT) -> VOID
 *=================================*/
PVALUE
llrpt_col (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	INT newcol=0;
	PNODE argvar = builtin_args(node);
	PVALUE val = eval_and_coerce(PINT, argvar, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, argvar, val, nonint1, "col");
		delete_pvalue_ptr(&val);
		return NULL;
	}
	newcol = pvalue_to_int(val);
	delete_pvalue_ptr(&val);
	if (newcol < 1) newcol = 1;
	if (newcol > MAXCOLS) newcol = MAXCOLS;
	if (newcol == curcol) return NULL;
	if (newcol < curcol)
		poutput("\n", eflg);
	while (curcol < newcol && !(*eflg))
		poutput(" ", eflg);
	return NULL;
}
Exemple #17
0
/*====================================+
 * llrpt_inset -- See if person is in INDISEQ
 * usage: inset(SET, INDI) -> BOOL
 *==========================================*/
PVALUE
llrpt_inset (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	NODE indi;
	STRING key=0;
	INDISEQ seq;
	BOOLEAN rel;
	PNODE arg1 = builtin_args(node), arg2 = inext(arg1);
	PVALUE val1 = eval_and_coerce(PSET, arg1, stab, eflg);
	PVALUE valr=0;
	if (*eflg ||!val1 || !(seq = pvalue_to_seq(val1))) {
		*eflg = TRUE;
		prog_var_error(node, stab, arg1, val1, nonsetx, "inset", "1");
		goto inset_exit;
	}
	indi = eval_indi(arg2, stab, eflg, NULL);
	if (*eflg) {
		prog_var_error(node, stab, arg2, NULL, nonindx, "inset", "2");
		goto inset_exit;
	}
	if (!indi) {
		rel = FALSE;
        } else { 
		if (!(key = strsave(rmvat(nxref(indi))))) {
			*eflg = TRUE;
			prog_error(node, "major error in inset.");
			goto inset_exit;
		}
		rel = in_indiseq(seq, key);
	}
	valr = create_pvalue_from_bool(rel);
inset_exit:
	/* delay delete of val1 to last minute lest it is a temp owning seq,
	    eg, inset(ancestorset(i),j) */
	if (val1) delete_pvalue(val1);
	if (key) strfree(&key);
	return valr;
}
Exemple #18
0
/*=======================================
 * llrpt_addnode -- Add a node to a GEDCOM tree
 * usage: addnode(NODE, NODE, NODE) -> VOID
 * args: (node being added, parent, previous child)
 *=====================================*/
PVALUE
llrpt_addnode (PNODE node, SYMTAB stab, BOOLEAN *eflg)
{
	PNODE arg = iargs(node);
	NODE newchild, next, prnt, prev;

	/* first argument, node (must be nonnull) */
	PVALUE val = eval_and_coerce(PGNODE, arg, stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg, val, nonnodx, "addnode", "1");
		delete_pvalue(val);
		return NULL;
	}
	newchild = remove_node_and_delete_pvalue(&val);
	if (!newchild) {
		prog_var_error(node, stab, arg, val, nonnodx, "addnode", "1");
		return NULL;
	}

	/* second argument, parent (must be nonnull) */
	val = eval_and_coerce(PGNODE, arg=inext(arg), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg, val, nonnodx, "addnode", "2");
		return NULL;
	}
	prnt = remove_node_and_delete_pvalue(&val);
	if (!prnt) {
		prog_var_error(node, stab, arg, val, nonnodx, "addnode", "2");
		return NULL;
	}

	/* third argument, prior sibling (may be null) */
	val = eval_and_coerce(PGNODE, arg=inext(arg), stab, eflg);
	if (*eflg) {
		prog_var_error(node, stab, arg, val, nonnodx, "addnode", "3");
		delete_pvalue(val);
		return NULL;
	}
	prev = remove_node_and_delete_pvalue(&val);

	if (prev) {
		/* Check that previous sibling actually is child of new parent */
		if (prnt != nparent(prev)) {
			prog_error(node, "2nd arg to addnode must be parent of 3rd arg");
			*eflg = 1;
			return NULL;
		}
	}

	/* reparent node, but ensure its locking is only relative to new parent */
	dolock_node_in_cache(newchild, FALSE);
	nparent(newchild) = prnt;
	newchild->n_cel = prnt->n_cel;
	set_temp_node(newchild, is_temp_node(prnt));
	dolock_node_in_cache(newchild, TRUE);
	if (prev == NULL) {
		next = nchild(prnt);
		nchild(prnt) = newchild;
	} else {
		next = nsibling(prev);
		nsibling(prev) = newchild;
	}
	nsibling(newchild) = next;
	return NULL;
}