/*====================================== * llrpt_writeindi -- Write person to database * usage: writeindi(INDI) -> BOOLEAN *====================================*/ PVALUE llrpt_writeindi (PNODE node, SYMTAB stab, BOOLEAN *eflg) { NODE indi1; PNODE arg = iargs(node); NODE indi2 = eval_indi(arg, stab, eflg, NULL); STRING rawrec=0, msg; INT len, cnt; BOOLEAN rtn=FALSE; if (*eflg || !indi2) { prog_var_error(node, stab, arg, 0, nonind1, "writeindi"); return NULL; } /* make a copy, so we can delete it */ indi2 = copy_node_subtree(indi2); /* get existing record */ rawrec = retrieve_raw_record(rmvat(nxref(indi2)), &len); if (!rawrec) { /* TODO: What do we do here ? Are they adding a new indi ? or did they get the xref wrong ? */ goto end_writeindi; } ASSERT(indi1 = string_to_node(rawrec)); cnt = resolve_refn_links(indi2); /* validate for showstopper errors */ if (!valid_indi_tree(indi2, &msg, indi1)) { /* TODO: What to do with msg ? */ goto end_writeindi; } if (cnt > 0) { /* unresolvable refn links */ /* TODO: optional argument to make this fatal ? */ } if (equal_tree(indi1, indi2)) { /* optimization :) */ rtn = TRUE; goto end_writeindi; } if (readonly) { /* TODO: database is read only error message */ goto end_writeindi; } replace_indi(indi1, indi2); strfree(&rawrec); rtn = TRUE; end_writeindi: return create_pvalue_from_bool(rtn); }
/*===========================================+ * 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; }
/*==================================+ * 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; }
/*====================================+ * 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; }