/*====================================================== * choose_from_indiseq -- Format sequence and have user * choose from it (any type) * This handles bad pointers, which can get into the data * several ways. * seq: [IN] sequence from which to choose * ask1: [IN] whether to prompt if only one element in sequence * titl1: [IN] title if sequence has one element * titln: [IN] title if sequence has multiple elements *=====================================================*/ RECORD choose_from_indiseq (INDISEQ seq, ASK1Q ask1, STRING titl1, STRING titln) { INT i = 0; RECORD rec=0; i = choose_one_from_indiseq_if_needed(seq, ask1, titl1, titln); if (i == -1) return NULL; listbadkeys=1; /* which typed value indiseq is this ? */ if (!indiseq_is_valtype_ival(seq) && !indiseq_is_valtype_null(seq)) { /* int debug=1; */ /* Can this happen ? */ } if (-1 == get_indiseq_ival(seq, i)) /* invalid pointer */ badkeylist[0] = 0; else { CNSTRING skey = element_key_indiseq(seq, i); rec = key_to_record(skey); } listbadkeys = 0; if(!rec) { char buf[132]; if (badkeylist[0]) llstrncpyf(buf, sizeof(buf), uu8, "%s: %.40s", _(qSmisskeys), badkeylist); else llstrncpyf(buf, sizeof(buf), uu8, _(qSbadkeyptr)); message(buf); } return rec; }
/*============================================ * cgr_callback -- callback for refn traversal * for checking for ghost refns * Created: 2001/01/13, Perry Rapp *==========================================*/ static BOOLEAN cgr_callback (TRAV_REFNS_FUNC_ARGS(key, refn, newset, param)) { /* a refn record which points at record=key */ RECORD rec = key_to_record(key); NODE node = nztop(rec); param = param; /* unused */ if (newset) { finish_and_delete_refnset(); soundexseq = create_indiseq_sval(); } append_indiseq_sval(soundexseq, strsave(key), NULL, strsave(refn) , TRUE, TRUE); /* sure, alloc */ if (!node) { report_error(ERR_ORPHANNAME, _("Orphaned refn: %s"), refn); if (todo.fix_ghosts) enqueue_list(tofix, (VPTR)alloc_namerefn(refn, key, ERR_ORPHANNAME)); } else { } if (noisy) report_progress("Refn: %s", refn); return 1; /* continue traversal */ }
/*================================= * fix_nodes -- Fix all nodes on fix list * (uses list from check_nodes) *================================*/ static void fix_nodes (void) { if (!tofix) return; while (!is_empty_list(tofix)) { STRING key = dequeue_list(tofix); RECORD rec = key_to_record(key); strfree(&key); lock_record_in_cache(rec); process_record(rec); unlock_record_from_cache(rec); } }
/*================================================ * edit_add_record -- Add record to database by editing * recstr: [IN] default record * redt: [IN] re-edit message * ntype, [IN] S, E, or X * cfrm: [IN] confirm message *==============================================*/ static RECORD edit_add_record (STRING recstr, STRING redt, STRING redtopt, char ntype, STRING cfrm) { FILE *fp; NODE node=0, refn; STRING msg, key; BOOLEAN emp; XLAT ttmi = transl_get_predefined_xlat(MEDIN); STRING (*getreffnc)(void) = NULL; /* get next internal key */ void (*todbasefnc)(NODE) = NULL; /* write record to dbase */ void (*tocachefnc)(NODE) = NULL; /* write record to cache */ /* set up functions according to type */ if (ntype == 'S') { getreffnc = getsxref; todbasefnc = sour_to_dbase; tocachefnc = sour_to_cache; } else if (ntype == 'E') { getreffnc = getexref; todbasefnc = even_to_dbase; tocachefnc = even_to_cache; } else { /* X */ getreffnc = getxxref; todbasefnc = othr_to_dbase; tocachefnc = othr_to_cache; } /* Create template for user to edit */ if (!(fp = fopen(editfile, LLWRITETEXT))) { msg_error(_(qSnofopn), editfile); return FALSE; } prefix_file_for_edit(fp); fprintf(fp, "%s\n", recstr); /* Have user edit new record */ fclose(fp); do_edit(); while (TRUE) { INT cnt; node = file_to_node(editfile, ttmi, &msg, &emp); if (!node) { if (ask_yes_or_no_msg(msg, redt)) { /* yes, edit again */ do_edit(); continue; } break; } cnt = resolve_refn_links(node); /* check validation & allow user to reedit if invalid */ /* this is a showstopper, so alternative is to abort */ if (!valid_node_type(node, ntype, &msg, NULL)) { if (ask_yes_or_no_msg(msg, redt)) { do_edit(); continue; } free_nodes(node); node = NULL; /* fail out */ break; } /* Allow user to reedit if desired if any refn links unresolved */ /* this is not a showstopper, so alternative is to continue */ if (cnt > 0) { char msgb[120]; snprintf(msgb, sizeof(msgb) , get_unresolved_ref_error_string(cnt), cnt); if (ask_yes_or_no_msg(msgb, redtopt)) { write_node_to_editfile(node); do_edit(); continue; } } break; } if (!node || !ask_yes_or_no(cfrm)) { if (node) free_nodes(node); return NULL; } nxref(node) = strsave((STRING)(*getreffnc)()); key = rmvat(nxref(node)); for (refn = nchild(node); refn; refn = nsibling(refn)) { if (eqstr("REFN", ntag(refn)) && nval(refn)) add_refn(nval(refn), key); } (*todbasefnc)(node); (*tocachefnc)(node); return key_to_record(key); }