/*================================================= * ask_for_indiseq -- Ask user to identify sequence * ttl: [IN] prompt (title) to display * ctype: [IN] type of record (eg, 'I') (0 for any) * prc: [OUT] result code (RC_DONE, RC_SELECT, RC_NOSELECT) *===============================================*/ INDISEQ ask_for_indiseq (CNSTRING ttl, char ctype, INT *prc) { while (1) { INDISEQ seq=0; char name[MAXPATHLEN]; *prc = RC_DONE; if (!ask_for_string(ttl, _(qSidbrws), name, sizeof(name))) return NULL; if (!name || *name == 0) return NULL; *prc = RC_NOSELECT; if (eqstr(name, "@")) { seq = invoke_search_menu(); if (!seq) continue; /* fallback to main question above */ *prc = RC_SELECT; } else { seq = str_to_indiseq(name, ctype); if (seq) { *prc = RC_SELECT; } else { msg_error(_(qSnonamky)); continue; } } return seq; } }
/*=========================================== * ask_for_int -- Ask user to provide integer * titl: [IN] prompt title * TODO: change to BOOLEAN return for failure *=========================================*/ BOOLEAN ask_for_int (STRING ttl, INT * prtn) { INT ival, c, neg; char buffer[MAXPATHLEN]; while (TRUE) { STRING p = buffer; if (!ask_for_string(ttl, _(qSaskint), buffer, sizeof(buffer))) return FALSE; neg = 1; while (iswhite(*p++)) ; --p; if (*p == '-') { neg = -1; p++; while (iswhite(*p++)) ; --p; } if (chartype(*p) == DIGIT) { ival = *p++ - '0'; while (chartype(c = *p++) == DIGIT) ival = ival*10 + c - '0'; --p; while (iswhite(*p++)) ; --p; if (*p == 0) { *prtn = ival*neg; return TRUE; } } } }
/*=============================================== * ask_for_record_key -- Ask user to enter record key * returns NULL or strsave'd answer *=============================================*/ STRING ask_for_record_key (STRING title, STRING prompt) { char answer[MAXPATHLEN]; if (!ask_for_string(title, prompt, answer, sizeof(answer))) return NULL; if (!answer) return NULL; return strsave(answer); }
/*=============================================== * ask_for_record -- Ask user to identify record * lookup by key or by refn (& handle dup refns) * idstr: [IN] question prompt * letr: [IN] letter to possibly prepend to key (ie, I/F/S/E/X) *=============================================*/ RECORD ask_for_record (STRING idstr, INT letr) { RECORD rec; char answer[MAXPATHLEN]; if (!ask_for_string(idstr, _(qSidkyrfn), answer, sizeof(answer)) || !answer[0]) return NULL; rec = key_possible_to_record(answer, letr); if (!rec) { INDISEQ seq; seq = refn_to_indiseq(answer, letr, KEYSORT); if (!seq) return NULL; rec = choose_from_indiseq(seq, NOASK1, _(qSduprfn), _(qSduprfn)); remove_indiseq(seq); } return rec; }
/*=================================================== * who_is_he_she -- Find who person is from key value *=================================================*/ void who_is_he_she (void) { STRING str, rawrec; NODE indi; INT len; char nkey[100]; char key[20]; if (!ask_for_string(_("Please enter person's internal key value."), _("enter key:"), key, sizeof(key)) || !key[0]) return; nkey[0] = 'I'; if (*key == 'I') strcpy(nkey, key); else strcpy(&nkey[1], key); if (!(rawrec = retrieve_raw_record(nkey, &len))) { msg_error(_("No one in database has key value %s."), key); return; } if (!(indi = string_to_node(rawrec))) { msg_error(_("No one in database has key value %s."), key); stdfree(rawrec); return; } if (!(str = indi_to_name(indi, 60)) || *str == 0) { msg_error(_("No one in database has key value %s."), key); stdfree(rawrec); return; } msg_info("%s - %s", key, str); /* LEAK -- where is stdfree(rawrec) -- Perry 2001/11/18 */ }
/*================================================= * do_import -- Read GEDCOM file to database * ifeed: [IN] output methods * fp: [I/O] GEDCOM file whence to load data *===============================================*/ static BOOLEAN do_import (IMPORT_FEEDBACK ifeed, FILE *fp) { NODE node, conv; XLAT ttm = 0; STRING msg; BOOLEAN emp; INT nindi = 0, nfam = 0, neven = 0; INT nsour = 0, nothr = 0, type, num = 0; INT totkeys = 0, totused = 0; char msgbuf[80]; BOOLEAN succeeded=FALSE; STRING str,unistr=0; ZSTR zerr=0; TABLE metadatatab = create_table_str(); STRING gdcodeset=0; INT warnings=0; /* start by assuming default */ strupdate(&gdcodeset, gedcom_codeset_in); /* rptui_init(); *//* clear ui time counter */ /* Open and validate GEDCOM file */ if ((unistr=check_file_for_unicode(fp)) && !eqstr(unistr, "UTF-8")) { msg_error(_(qSunsupuniv), unistr); goto end_import; } if (eqstr_ex(unistr, "UTF-8")) { strupdate(&gdcodeset, "UTF-8"); } if (!scan_header(fp, metadatatab, &zerr)) { msg_error(zs_str(zerr)); goto end_import; } if ((str = valueof_str(metadatatab, "GEDC.FORM"))!= NULL) { if (!eqstr(str, "LINEAGE-LINKED")) { if (!ask_yes_or_no_msg( _("This is not a lineage linked GEDCOM file.") , _("Proceed anyway?") )) goto end_import; } } if (!unistr && (str = valueof_str(metadatatab, "CHAR"))!= NULL) { /* if no BOM, use file's declared encoding if present */ strupdate(&gdcodeset, str); } /* TODO: Push this codeset question down to after the validation, where we can know if the incoming file happened to really be all ASCII */ if (!int_codeset[0]) { /* TODO: ask if user would like to adopt codeset of incoming file, if we found it */ if (!ask_yes_or_no_msg( _("No current internal codeset, so no codeset conversion can be done") , _("Proceed without codeset conversion?") )) goto end_import; } /* Warn if lossy code conversion likely */ if (gdcodeset[0] && int_codeset[0]) { if (is_lossy_conversion(gdcodeset, int_codeset)) { ZSTR zstr=zs_new(); zs_setf(zstr, _("Lossy codeset conversion (from <%s> to <%s>) likely") , gdcodeset, int_codeset); if (!ask_yes_or_no_msg( zs_str(zstr) , _("Proceed anyway?") )) goto end_import; } } /* validate */ if (ifeed && ifeed->validating_fnc) (*ifeed->validating_fnc)(); if (!validate_gedcom(ifeed, fp)) { if (ifeed && ifeed->error_invalid_fnc) (*ifeed->error_invalid_fnc)(_(qSgdnadd)); goto end_import; } warnings = validate_get_warning_count(); if (warnings) { ZSTR zstr=zs_new(); zs_setf(zstr, _pl("%d warning during import", "%d warnings during import", warnings), warnings); if (!ask_yes_or_no_msg(zs_str(zstr), _(qSproceed))) { goto end_import; } } if (gdcodeset[0] && int_codeset[0]) { retry_input_codeset: ttm = transl_get_xlat(gdcodeset, int_codeset); if (!transl_is_xlat_valid(ttm)) { ZSTR zstr=zs_new(); char csname[64]; BOOLEAN b; transl_release_xlat(ttm); ttm = 0; zs_setf(zstr, _("Cannot convert codeset (from <%s> to <%s>)") , gdcodeset, int_codeset); b = ask_for_string(zs_str(zstr) , _("Enter codeset to assume (* for none)") , csname, sizeof(csname)) && csname[0]; zs_free(&zstr); if (!b) goto end_import; if (!eqstr(csname, "*")) { strupdate(&gdcodeset, csname); goto retry_input_codeset; } } } if((num_indis() > 0) || (num_fams() > 0) || (num_sours() > 0) || (num_evens() > 0) || (num_othrs() > 0)) gd_reuse = FALSE; else if((gd_reuse = check_stdkeys())) { totused = gd_itot + gd_ftot + gd_stot + gd_etot + gd_xtot; totkeys = gd_imax + gd_fmax + gd_smax + gd_emax + gd_xmax; if((totkeys-totused) > 0) { INT delkeys = totkeys-totused; snprintf(msgbuf, sizeof(msgbuf) , _pl("Using original keys, %d deleted record will be in the database." , "Using original keys, %d deleted records will be in the database." , delkeys) , delkeys ); } else strcpy(msgbuf, " "); gd_reuse = ask_yes_or_no_msg(msgbuf, _(qScfoldk)); /* TODO: why were these here ? touchwin(uiw_win(stdout_win)); wrefresh(uiw_win(stdout_win)); */ } /* start loading the file */ rewind(fp); /* test for read-only database here */ if(readonly) { if (ifeed && ifeed->error_readonly_fnc) (*ifeed->error_readonly_fnc)(); goto end_import; } /* tell user we are beginning real part of import */ if (ifeed && ifeed->beginning_import_fnc) { if(gd_reuse) (*ifeed->beginning_import_fnc)(_(qSdboldk)); else (*ifeed->beginning_import_fnc)(_(qSdbnewk)); } /* Add records to database */ node = convert_first_fp_to_node(fp, FALSE, ttm, &msg, &emp); while (node) { if (!(conv = node_to_node(node, &type))) { free_nodes(node); node = next_fp_to_node(fp, FALSE, ttm, &msg, &emp); continue; } switch (type) { case INDI_REC: num = ++nindi; break; case FAM_REC: num = ++nfam; break; case EVEN_REC: num = ++neven; break; case SOUR_REC: num = ++nsour; break; case OTHR_REC: num = ++nothr; break; default: FATAL(); } restore_record(conv, type, num); if (ifeed && ifeed->added_rec_fnc) ifeed->added_rec_fnc(nxref(conv)[1], ntag(conv), num); free_nodes(node); node = next_fp_to_node(fp, FALSE, ttm, &msg, &emp); } if (msg) { msg_error(msg); } if(gd_reuse && ((totkeys - totused) > 0)) { if (ifeed && ifeed->adding_unused_keys_fnc) (*ifeed->adding_unused_keys_fnc)(); addmissingkeys(INDI_REC); addmissingkeys(FAM_REC); addmissingkeys(EVEN_REC); addmissingkeys(SOUR_REC); addmissingkeys(OTHR_REC); } succeeded = TRUE; end_import: validate_end_import(); zs_free(&zerr); destroy_table(metadatatab); strfree(&gdcodeset); return succeeded; }