/* * @progname extract_set.li * @version 1.5 * @author Scott McGee (smcgee@microware.com) * @category * @output function values * @description A library containing routines to allow extraction of a set of related persons from a database. The function extract_set() is passed a starting indi, and traverses selected persons relatives until no selections are left. It returns an indi set of the selected persons. The do_info() function will return a string containing the name and birth/ death type info on the indi passed as a parameter. @(#)extract_set.li 1.5 10/13/95 */ func extract_set(indi){ list(w) /* working list */ indiset(o) /* output set */ indiset(out) /* output set */ table(t) /* table of seen persons */ indiset(us) /* temporary set */ set(first, 1) set(count, 1) enqueue(w, indi) while (indi, dequeue(w)) { if (not(lookup(t, key(indi)))) { insert(t, key(indi), 1) if (askabout(indi)) { addtoset(o, indi, count) incr(count) if (j, father(indi)) { enqueue(w, j) } if (j, mother(indi)) { enqueue(w, j) } families(indi, f, s, n) { if(s) { enqueue(w, s) } children(f, j, m) { enqueue(w, j) } } } } } print("You selected ", d(lengthset(o)), " individuals.\n") set(useout, 0) set(msg, "Do you want all the ancestors of these people added to this set? (y or n) ") getstr(answer, msg) if(eqstr(lower(trim(answer, 1)), "y")) { set(anc, ancestorset(o)) if(anc) { print("Found ", d(lengthset(difference(anc, intersect(anc, o)))), " additional ancestors.\n") set(out, union(o, anc)) set(rel, get_relatives(out)) if(rel){ print("Found ", d(lengthset(difference(rel, intersect(rel, out)))), " additional relatives.\n") set(out, union(out, rel)) } set(useout, 1) }else{ print("no ancestors found\n") } }else{ set(msg, concat("Do you want all the ancestors of ", name(first_indi), " added to this set? (y or n) ")) getstr(answer, msg) if(eqstr(lower(trim(answer, 1)), "y")) { set(m, 1) addtoset(us, first_indi, m) if(us) { set(anc, ancestorset(us)) if(anc) { print("Found ", d(lengthset(difference(anc, intersect(anc, o)))), " additional ancestors.\n") set(out, union(o, anc)) set(rel, get_relatives(out)) if(rel){ print("Found ", d(lengthset(difference(rel, intersect(rel, out)))), " additional relatives.\n") set(out, union(out, rel)) } set(useout, 1) }else{ print("no ancestors found\n") } }else{ print("error: nobody in 'us' set\n") } } } set(msg, "Do you want all the descendants of these people added to this set? (y or n) ") getstr(answer, msg) if(eqstr(lower(trim(answer, 1)), "y")) { set(anc, descendantset(o)) if(anc) { if(useout){ print("Found ", d(lengthset(difference(anc, intersect(anc, out)))), " additional descendants.\n") set(out, union(out, anc)) }else{ print("Found ", d(lengthset(difference(anc, intersect(anc, o)))), " additional descendants.\n") set(out, union(o, anc)) } set(rel, get_relatives(union(o, anc))) if(rel){ print("Found ", d(lengthset(difference(rel, intersect(rel, out)))), " additional relatives.\n") set(out, union(out, rel)) } }else{ print("no descendantss found\n") } }else{ set(msg, concat("Do you want all the descendants of ", name(first_indi), " added to this set? (y or n) ")) getstr(answer, msg) if(eqstr(lower(trim(answer, 1)), "y")) { set(m, 1) addtoset(us, first_indi, m) if(us) { set(anc, descendantset(us)) if(anc) { if(useout){ print("Found ", d(lengthset(difference(anc, intersect(anc, out)))), " additional descendants.\n") set(out, union(out, anc)) }else{ print("Found ", d(lengthset(difference(anc, intersect(anc, o)))), " additional descendants.\n") set(out, union(o, anc)) } set(rel, get_relatives(anc)) if(rel){ print("Found ", d(lengthset(difference(rel, intersect(rel, out)))), " additional relatives.\n") set(out, union(out, rel)) } }else{ print("no descendants found\n") } }else{ print("error: nobody in 'us' set\n") } } if(not(useout)){ set(out, o) } } return(out) } func askabout (indi) { if(not(first)) { call showinfo(indi) set(s, concat("Do you want ", name(indi), " in your output files? (y or n) ")) getstr(a, s) return (eqstr(lower(trim(a, 1)), "y")) }else{ set(first, 0) return (1) } } proc showinfo (indi) { print(name(indi), do_info(indi), " (", key(indi), ")\n\n") set(did_afn, afn(indi)) print("Father: ", name(father(indi)), do_info(father(indi)), "\n") print("Mother: ", name(mother(indi)), do_info(mother(indi)), "\n\n\n\n\n\n\n") set(f, 0) set(s, 0) families(indi, fa, sp, n) { if (eq(1, n)) { set(f, fa) set(s, sp) } } print("Married: ", long(marriage(f)), "\n") print("Spouse: ", name(s), do_info(s), "\n\n\n\n\n") if(not(did_afn)){ print("\n") } } func do_info(me){ if(not(me)){ return("") }else{ set(out, " -") if (evt, birth(me)) { set(out, concat(out, " born ", short(evt))) } else { if (evt, baptism(me)) { set(out, concat(out, " baptised ", short(evt))) } else { if (evt, bapt(me)) { set(out, concat(out, " baptised ", short(evt))) } } } if (evt, death(me)) { set(out, concat(out, " died ", short(evt))) } return(out) } } func afn(indi){ if(indi){ fornodes(inode(indi), subnode){ if(eqstr(tag(subnode), "AFN")){ print("AFN ", value(subnode), "\n") return(1) } } } return(0) } func get_relatives(in_set){ set(msg, "Do you want to add all relatives within a given link distance? (y or n) ") getstr(answer, msg) if(eqstr(lower(trim(answer, 1)), "y")) { getint(n, "Please enter link distance.") /* create set with all ancestors and descendents */ indiset(out_set) indiset(t) /* temporary working set */ /* create set of additional, linked-to persons */ set(t, in_set) while (gt(n, 0)) { set(a, parentset(t)) set(b, childset(t)) set(c, spouseset(t)) set(t, union(t, union(a, union(b, c)))) set(n, sub(n, 1)) } set(out_set, t) return(out_set) } return(0) }