Exemple #1
0
/*===============================================================
 * disp_shrt_format_date -- short form of date for display
 *  This is used for dates in option strings, and in single-line
 *  descriptions of people (ie, in event summaries).
 * Created: 2001/10/29 (Perry Rapp)
 *=============================================================*/
static STRING
disp_shrt_format_date (STRING date)
{
	INT dfmt=0,mfmt=0,yfmt=0,sfmt=0,efmt=0, cmplx;
	INT n;
	STRING fmts, pic;

	if (!date) return NULL;

	n = 0;
	fmts = getlloptstr("ShortDisplayDate", NULL);
	if (fmts) {
		/* try to use user-specified format */
		n = sscanf(fmts, "%ld,%ld,%ld,%ld,%ld,%ld"
			, &dfmt, &mfmt, &yfmt, &sfmt, &efmt, &cmplx);
	}
	if (n != 6) {
		dfmt=mfmt=yfmt=sfmt=cmplx=0;
		sfmt=12; /* old style short form -- year only */
	}

	pic = getlloptstr("ShortDisplayDatePic", NULL);
	if (pic && pic[0])
		set_date_pic(pic);

	return do_format_date(date, dfmt, mfmt, yfmt, sfmt, efmt, cmplx);
}
Exemple #2
0
/*===========================================================
 * disp_long_format_date -- Convert date according to options
 *=========================================================*/
static STRING
disp_long_format_date (STRING date)
{
	INT dfmt=0,mfmt=0,yfmt=0,sfmt=0,efmt=0, cmplx;
	INT n;
	STRING fmts, pic;

	if (!date) return NULL;

	n = 0;
	fmts = getlloptstr("LongDisplayDate", NULL);
	if (fmts) {
		/* try to use user-specified format */
		n = sscanf(fmts, "%ld,%ld,%ld,%ld,%ld,%ld" 
			, &dfmt, &mfmt, &yfmt, &sfmt, &efmt, &cmplx);
	}
	if (n != 6) {
		dfmt=mfmt=yfmt=sfmt=efmt=cmplx=0;
		sfmt=14; /* GEDCOM as is */
	}

	pic = getlloptstr("LongDisplayDatePic", NULL);
	if (pic && pic[0])
		set_date_pic(pic);
	
	return do_format_date(date, dfmt, mfmt, yfmt, sfmt, efmt, cmplx);
}
Exemple #3
0
/*================================
 * save_gedcom -- save gedcom file
 *==============================*/
BOOLEAN
save_gedcom (void)
{
    FILE *fp=NULL;
    struct tag_export_feedback efeed;
    STRING srcdir=NULL, fname=0, fullpath=0;

    srcdir = getlloptstr("LLARCHIVES", ".");
    fp = ask_for_output_file(LLWRITETEXT, _(qSoutarc), &fname, &fullpath, srcdir, ".ged");
    if (!fp) {
        strfree(&fname);
        msg_error(_("The database was not saved."));
        return FALSE;
    }
    prefix_file_for_gedcom(fp);

    memset(&efeed, 0, sizeof(efeed));
    efeed.added_rec_fnc = export_saved_rec;

    llwprintf(_("Saving database `%s' in file `%s'."), readpath_file, fullpath);

    /* Display 0 counts */
    clear_rec_counts(0);

    archive_in_file(&efeed, fp);
    fclose(fp);

    wpos(7,0);
    msg_info(_(qSoutfin), readpath_file, fname);
    strfree(&fname);

    return TRUE;
}
Exemple #4
0
/*==========================================================
 * transl_load_all_tts -- Load internal list of available translation
 *  tables (based on *.tt files in TTPATH)
 * Created: 2002/11/28 (Perry Rapp)
 *========================================================*/
void
transl_load_all_tts (void)
{
    CNSTRING ttpath = getlloptstr("TTPATH", ".");
    if (!inited) local_init();
    xl_load_all_dyntts(ttpath);
}
Exemple #5
0
/*======================================+
 * set_output_file -- Open specified output file
 *  (Closes any previously open output file)
 * Calls msg_error & returns FALSE, if problem
 *=====================================*/
static BOOLEAN
set_output_file (STRING outfname, BOOLEAN append)
{
	STRING modestr = append ? LLAPPENDTEXT:LLWRITETEXT;
	STRING rptdir=0;
	if (Poutfp) {
		finishrassa();
		fclose(Poutfp);
		Poutfp = NULL;
	}
	rptdir = getlloptstr("LLREPORTS", ".");
	Poutfp = fopenpath(outfname, modestr, rptdir, NULL, uu8, NULL);
	if (!Poutfp) {
		/* TODO: need to forward this through rptui */
		msg_error(_("Could not open file %s"), outfname);
		return FALSE;
	}
	/* if appending to existing non-empty file, don't add BOM */
	if (append) {
		long offset = 0;
		fseek(Poutfp, 0, SEEK_END);
		offset = ftell(Poutfp);
		if (offset > 0)
			return TRUE;
	}
	prefix_file_for_report(Poutfp);
	return TRUE;
}
Exemple #6
0
/*====================================+
 * request_file -- Prompt user for file name
 *  returns open file pointer, or NULL if error
 *  handles error message
 * Created: 2002/01/18
 *===================================*/
static BOOLEAN
request_file (BOOLEAN *eflg)
{
	STRING rptdir = getlloptstr("LLREPORTS", ".");
	STRING fname=0, fullpath=0;
	Poutfp = rptui_ask_for_output_file(LLWRITETEXT, _(qSwhtout), &fname
		, &fullpath, rptdir, NULL);
	if (!Poutfp || !fname || !fname[0])  {
		if (fname)
			prog_error(0, _("Report stopping due to error opening output file"));
		else
			prog_error(0, _("Report stopping due to lack of output file"));
		/* set error flag to stop interpreter */
		*eflg = TRUE;
		/* set cancel flag to suppress traceback */
		rpt_cancelled = TRUE;
		strfree(&fname);
		return FALSE;
	}
	if (outfilename)
		stdfree(outfilename);
	outfilename = fullpath;
	strfree(&fname);
	prefix_file_for_report(Poutfp);
	return TRUE;
}
Exemple #7
0
/*================================
 * load_gedcom -- have user select gedcom file & import it
 *==============================*/
void
load_gedcom (BOOLEAN picklist)
{
    FILE *fp=NULL;
    struct tag_import_feedback ifeed;
    STRING srcdir=NULL;
    STRING fullpath=0;
    time_t begin = time(NULL);
    time_t beginui = get_uitime();

    srcdir = getlloptstr("InputPath", ".");
    if (!ask_for_gedcom(LLREADTEXT, _(qSwhatgedc), 0, &fullpath, srcdir, ".ged", picklist)
            || !(fp = fopen(fullpath, LLREADBINARY))) {
        strfree(&fullpath);
        return;
    }

    /*
    Note: we read the file in binary mode, so ftell & fseek will work correctly.
    Microsoft's ftell/fseek do not work correctly if the file has simple unix (\n)
    line terminations! -- Perry, 2003-02-11
    */

    memset(&ifeed, 0, sizeof(ifeed));
    ifeed.validating_fnc = import_validating;
    ifeed.validated_rec_fnc = import_validated_rec;
    ifeed.beginning_import_fnc = import_beginning_import;
    ifeed.error_invalid_fnc = import_error_invalid;
    ifeed.error_readonly_fnc = import_readonly;
    ifeed.adding_unused_keys_fnc = import_adding_unused_keys;
    ifeed.added_rec_fnc = import_added_rec;
    ifeed.validation_error_fnc = import_validation_error;
    ifeed.validation_warning_fnc =  import_validation_warning;

    import_from_gedcom_file(&ifeed, fp);

    fclose(fp);
    strfree(&fullpath);


    if (1) {
        INT duration = time(NULL) - begin;
        INT uitime = get_uitime() - beginui;
        ZSTR zt1=approx_time(duration-uitime), zt2=approx_time(uitime);
        /* TRANSLATORS: how long Import ran, and how much of that was UI delay */
        ZSTR zout = zs_newf(_("Import time %s (ui %s)\n")
                            , zs_str(zt1), zs_str(zt2));
        wfield(8,0, zs_str(zout));
        zs_free(&zt1);
        zs_free(&zt2);
        zs_free(&zout);
    }

    /* position cursor further down stdout so check_stdout
    doesn't overwrite our messages from above */
    wpos(15,0);
}
Exemple #8
0
/*=============================================+
 * vprog_error -- Report a run time program error
 *  node:        current parsed node
 *  fmt, args:   printf style message
 *  ...:    printf style varargs
 * Prints error to the stdout-style curses window
 * and to the report log (if one was specified in config file)
 * Always includes line number of node, if available
 * Only includes file name if not same as previous error
 * Returns static buffer with one-line description
 *============================================*/
static STRING
vprog_error (PNODE node, STRING fmt, va_list args)
{
	INT num;
	STRING rptfile;
	ZSTR zstr=zs_newn(256);
	static char msgbuff[100];
	if (rpt_cancelled)
		return _("Report cancelled");
	rptfile = getlloptstr("ReportLog", NULL);
	if (node) {
		STRING fname = irptinfo(node)->fullpath;
		INT lineno = iline(node)+1;
		/* Display filename if not same as last error */
		if (!eqstr(vprog_prevfile, fname)) {
			llstrsets(vprog_prevfile, sizeof(vprog_prevfile), uu8, fname);
			zs_apps(zstr, _("Report file: "));
			zs_apps(zstr, fname);
			zs_appc(zstr, '\n');
			vprog_prevline = -1; /* force line number display */
		}
		/* Display line number if not same as last error */
		if (vprog_prevline != lineno) {
			vprog_prevline = lineno;
			if (progparsing)
				zs_appf(zstr, _("Parsing Error at line %d: "), lineno);
			else
				zs_appf(zstr, _("Runtime Error at line %d: "), lineno);
		}
	} else {
		zs_apps(zstr, _("Aborting: "));
	}
	zs_appvf(zstr, fmt, args);
	llwprintf("\n");
	llwprintf(zs_str(zstr));
	++progerror;
	/* if user specified a report error log (in config file) */
	if (rptfile && rptfile[0]) {
		FILE * fp = fopen(rptfile, LLAPPENDTEXT);
		if (fp) {
			if (progerror == 1) {
				LLDATE creation;
				get_current_lldate(&creation);
				fprintf(fp, "\n%s\n", creation.datestr);
			}
			fprintf(fp, "%s", zs_str(zstr));
			fprintf(fp, "\n");
			fclose(fp);
		}
	}
	if ((num = getlloptint("PerErrorDelay", 0)))
		sleep(num);
	zs_free(&zstr);
	return msgbuff;
}
Exemple #9
0
/*====================================================
 * edit_add_other -- Add user record to database by editing
 *==================================================*/
RECORD
edit_add_other (void)
{
	STRING str;
	if (readonly) {
		message(_(qSronlya));
		return NULL;
	}
	str = getlloptstr("OTHR", _(qSdefothr));
	return edit_add_record(str, _(qSxredit), _(qSxreditopt), 'X', _(qScfxadd));
}
Exemple #10
0
/*================================================
 * edit_add_source -- Add source to database by editing
 *==============================================*/
RECORD
edit_add_source (void)
{
	STRING str;
	if (readonly) {
		message(_(qSronlya));
		return NULL;
	}
	str = getlloptstr("SOURREC", _(qSdefsour));
	return edit_add_record(str, _(qSrredit), _(qSrreditopt), 'S', _(qScfradd));
}
Exemple #11
0
/*==============================================
 * edit_add_event -- Add event to database by editing
 *============================================*/
RECORD
edit_add_event (void)
{
	STRING str;
	if (readonly) {
		message(_(qSronlya));
		return NULL;
	}
	str = getlloptstr("EVENREC", _(qSdefeven));
	return edit_add_record(str, _(qSeredit), _(qSereditopt), 'E', _(qScfeadd));
}
Exemple #12
0
/*==================================================
 * load_configs -- Load global config file(s)
 * returns FALSE if error, with message in pmsg
 *================================================*/
static BOOLEAN
load_configs (STRING configfile, STRING * pmsg)
{
    INT rtn=0;
    STRING str=0;
    char cfg_name[MAXPATHLEN];

    /* TODO: Should read a system-wide config file */

    if (!configfile)
        configfile = getenv("LLCONFIGFILE");

    *pmsg = NULL;


    if (configfile && configfile[0]) {

        rtn = load_global_options(configfile, pmsg);
        if (rtn == -1) return FALSE;

    } else {

        /* No config file specified, so load config_file(s) from
           the standard places */

        /* look for global config file */
        llstrncpy(cfg_name, global_conf_path, sizeof(cfg_name), 0);
        llstrapps(cfg_name, sizeof(cfg_name), 0, "/lifelines.conf");
        rtn = load_global_options(cfg_name, pmsg);
        if (rtn == -1) return FALSE;

        /* look for one in user's home directory */
        /* TODO: Shouldn't Win32 use getenv("USERPROFILE") ? */
        llstrncpy(cfg_name, getenv("HOME") , sizeof(cfg_name), 0);
        /*llstrappc(cfg_name, sizeof(cfg_name), '/');*/
        llstrapps(cfg_name, sizeof(cfg_name), 0, "/" LINES_CONFIG_FILE);

        rtn = load_global_options(cfg_name, pmsg);
        if (rtn == -1) return FALSE;

        rtn = load_global_options(LINES_CONFIG_FILE, pmsg);
        if (rtn == -1) return FALSE;
    }

    /* allow chaining to one more config file
     * if one was defined for the database
     */
    str = getlloptstr("LLCONFIGFILE", NULL);
    if (str && str[0]) {
        rtn = load_global_options(str, pmsg);
        if (rtn == -1) return FALSE;
    }
    return TRUE;
}
Exemple #13
0
/*==================================================
 * select_database -- open database (prompting if appropriate)
 * if fail, return FALSE, and possibly a message to display
 *  perrmsg - [OUT]  translated error message
 *================================================*/
BOOLEAN
select_database (STRING dbrequested, INT alteration, STRING * perrmsg)
{
	STRING dbdir = getlloptstr("LLDATABASES", ".");
	STRING dbused = 0;

	/* Get Database Name (Prompt or Command-Line) */
	if (!dbrequested || !dbrequested[0]) {
		char dbname[MAXPATHLEN];
		/* ask_for_db_filename returns static buffer, we save it below */
		if (!ask_for_db_filename(_(qSidldir), _(qSidldrp), dbdir, dbname, sizeof(dbname))
			|| !dbname[0]) {
			dbrequested = NULL;
			*perrmsg = _(qSiddbse);
			return FALSE;
		}
		dbrequested = strsave(dbname);
		if (eqstr(dbrequested, "?")) {
			INT n=0;
			LIST dblist=0, dbdesclist=0;
			strfree(&dbrequested);
			if ((n=get_dblist(dbdir, &dblist, &dbdesclist)) > 0) {
				INT i;
				i = choose_from_list(
					_("Choose database to open")
					, dbdesclist);
				if (i >= 0) {
					dbrequested = strsave(get_list_element(dblist, i+1, NULL));
				}
				release_dblist(dblist);
				release_dblist(dbdesclist);
			} else {
				*perrmsg = _("No databases found in database path");
				return FALSE;
			}
			if (!dbrequested) {
				*perrmsg = _(qSiddbse);
				return FALSE;
			}
		}
	}

	/* search for database */
	/* search for file in lifelines path */
	dbused = filepath(dbrequested, "r", dbdir, NULL, uu8);
	/* filepath returns alloc'd string */
	if (!dbused) dbused = strsave(dbrequested);

	if (!open_or_create_database(alteration, &dbused)) {
		return FALSE;
	}

	return TRUE;
}
Exemple #14
0
/*==================================================
 * open_or_create_database -- open database, prompt for
 *  creating new one if it doesn't exist
 * if fails, displays error (show_open_error) and returns 
 *  FALSE
 *  alteration:   [IN]  flags for locking, forcing open...
 *  dbused:       [I/O] actual database path (may be relative)
 * If this routine creates new database, it will alter dbused
 * Created: 2001/04/29, Perry Rapp
 *================================================*/
BOOLEAN
open_or_create_database (INT alteration, STRING *dbused)
{
	INT lldberrnum=0;
	/* Open Database */
	if (open_database(alteration, *dbused, &lldberrnum))
		return TRUE;

	/* filter out real errors */
	if (lldberrnum != BTERR_NODB && lldberrnum != BTERR_NOKEY)
	{
		show_open_error(lldberrnum);
		return FALSE;
	}

	if (readonly || immutable || alteration)
	{
		llwprintf(_("Cannot create new database with -r, -i, -l, or -f flags."));
		return FALSE;
	}
	/*
	error was only that db doesn't exist, so lets try
	making a new one 
	If no database directory specified, add prefix llnewdbdir
	*/
	if (is_unadorned_directory(*dbused)) {
		STRING dbpath = getlloptstr("LLDATABASES", ".");
		CNSTRING newdbdir = get_first_path_entry(dbpath);
		STRING temp = *dbused;
		if (newdbdir) {
			char tempth[MAXPATHLEN];
			newdbdir = strdup(newdbdir);
			concat_path(newdbdir, *dbused, uu8, tempth, sizeof(tempth));
			*dbused = strsave(tempth);
			stdfree(temp);
			stdfree((STRING)newdbdir);
		}
	}

	/* Is user willing to make a new db ? */
	if (!ask_yes_or_no_msg(_(qSnodbse), _(qScrdbse))) 
		return FALSE;

	/* try to make a new db */
	if (create_database(*dbused, &lldberrnum))
		return TRUE;

	show_open_error(lldberrnum);
	return FALSE;
}
Exemple #15
0
/*=============================
 * create_table_impl -- Create table
 * All tables are created in this function
 * returns addref'd table
 *===========================*/
static TABLE
create_table_impl (enum TB_VALTYPE valtype, DELFUNC delfunc)
{
	TABLE tab = (TABLE) stdalloc(sizeof(*tab));

	tab->vtable = &vtable_for_table;
	tab->refcnt = 1;
	tab->valtype = valtype;
	if (getlloptstr("rbtree", 0))
		tab->rbtree = RbTreeCreate(tab, rbcompare, rbdestroy);
	else
		tab->hashtab = create_hashtab();
	tab->destroyfunc = delfunc;
	return tab;
}
Exemple #16
0
/*===================================================
 * update_useropts -- Set any global variables
 * dependent on user options
 *=================================================*/
void
update_useropts (VPTR uparm)
{
    uparm = uparm; /* unused */
    if (suppress_reload)
        return;
    /* deal with db-specific options */
    /* includes setting int_codeset */
    if (def_lldb)
        update_db_options();
    /* in case user changed any codesets */
    init_codesets();
    /* in case user changed locale (need int_codeset already set) */
    uilocale();
    /* in case user changed codesets */
    /* TODO: Isn't this superfluous, as it was called in update_db_options above ? */
    transl_load_xlats();

    strupdate(&illegal_char, getlloptstr("IllegalChar", 0));

    nodechk_enable(!!getlloptint("nodecheck", 0));
}
Exemple #17
0
/*==================================================
 * create_database -- create (& open) brand new database
 *  dbpath:  [IN]  path of database about to create
 *================================================*/
BOOLEAN
create_database (STRING dbpath, INT *lldberr)
{
	LLDATABASE lldb = lldb_alloc();
	BTREE btree = 0;

	/* first test that newdb props are legal */
	STRING props = getlloptstr("NewDbProps", 0);
	if (props && props[0]) {
		TABLE dbopts = create_table_str();
		STRING msg=0;
		if (!init_valtab_from_string(props, dbopts, '=', &msg)) {
			*lldberr = BTERR_BADPROPS;
			destroy_table(dbopts);
			return FALSE;
		}
		destroy_table(dbopts);
	}

	/* tentatively copy paths into gedlib module versions */
	readpath_file=strsave(lastpathname(dbpath));
	readpath=strsave(dbpath);

	if (!(btree = bt_openbtree(dbpath, TRUE, 2, immutable, lldberr))) {
		/* open failed so clean up, preserve lldberr */
		int myerr = *lldberr;
		lldb_close(&lldb);
		*lldberr = myerr;
		return FALSE;
	}
	def_lldb = lldb;
	lldb_set_btree(lldb, btree);
	initxref();
	if (props)
		store_record("VUOPT", props, strlen(props));
	return TRUE;
}
Exemple #18
0
/*===========================================
 * main -- Main procedure of dbverify command
 *=========================================*/
int
main (int argc, char **argv)
{
    char *flags, *dbname;
    char *ptr;
    char * msg;
    BOOLEAN cflag=FALSE; /* create new db if not found */
    INT writ=1; /* request write access to database */
    BOOLEAN immut=FALSE; /* immutable access to database */
    BOOLEAN allchecks=FALSE; /* if user requested all checks */
    INT returnvalue=1;
    STRING crashlog=NULL;
    INT lldberrnum=0;
    int i=0;

    /* initialize all the low-level library code */
    init_stdlib();

    validate_errs();

#if HAVE_SETLOCALE
    /* initialize locales */
    setlocale(LC_ALL, "");
#endif /* HAVE_SETLOCALE */

#if ENABLE_NLS
    ll_bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);
#endif

    save_original_locales();

#ifdef WIN32
    /* TO DO - research if this is necessary */
    _fmode = O_BINARY;	/* default to binary rather than TEXT mode */
#endif

    /* handle conventional arguments --version and --help */
    /* needed for help2man to synthesize manual pages */
    for (i=1; i<argc; ++i) {
        if (!strcmp(argv[i], "--version")) {
            print_version("dbverify");
            return 0;
        }
        if (!strcmp(argv[i], "--help")
                || !strcmp(argv[i], "-?")) {
            print_usage();
            return 0;
        }
    }

    if (argc != 3 || argv[1][0] != '-' || argv[1][1] == '\0') {
        print_usage();
        goto done;
    }
    flags = argv[1];
    dbname = argv[2];
    for (ptr=&flags[1]; *ptr; ++ptr) {
        switch(*ptr) {
        case 'l':
            todo.check_dbstructure=TRUE;
            break;
        case 'g':
            todo.find_ghosts=TRUE;
            break;
        case 'G':
            todo.fix_ghosts=TRUE;
            break;
        case 'i':
            todo.check_indis=TRUE;
            break;
        case 'f':
            todo.check_fams=TRUE;
            break;
        case 's':
            todo.check_sours=TRUE;
            break;
        case 'e':
            todo.check_evens=TRUE;
            break;
        case 'x':
            todo.check_othes=TRUE;
            break;
        case 'n':
            noisy=TRUE;
            break;
        case 'a':
            allchecks=TRUE;
            break;
        case 'F':
            todo.fix_alter_pointers=TRUE;
            break;
        case 'm':
            todo.check_missing_data_records=TRUE;
            break;
        case 'M':
            todo.fix_missing_data_records=TRUE;
            break;
        case 'D':
            todo.fix_deletes=TRUE;
            break;
        case 'v':
            print_version("llexec");
            goto done;
        case 'h':
        default:
            print_usage();
            goto done;
        }
    }

    /* Turn off Memory Debugging */
    /* This is unnecessary -- it is off anyway, Perry, 2001/10/28 */
    alloclog  = FALSE;

    /* Enable any checks needed for fixes selected */
    if (todo.fix_missing_data_records)
        todo.check_missing_data_records = 1;

    /* initialize options & misc. stuff */
    llgettext_set_default_localedir(LOCALEDIR);
    if (!init_lifelines_global(0, &msg, 0)) {
        printf("%s\n", msg);
        goto done;
    }

    /* setup crashlog in case init_screen fails (eg, bad menu shortcuts) */
    crashlog = getlloptstr("CrashLog_dbverify", NULL);
    if (!crashlog) {
        crashlog = "Crashlog_dbverify.log";
    }
    crash_setcrashlog(crashlog);

    /* NB: This assumes btree database */
    if (!(BTR = bt_openbtree(dbname, cflag, writ, immut, &lldberrnum))) {
        char buffer[256];
        describe_dberror(lldberrnum, buffer, ARRSIZE(buffer));
        puts(buffer);
        goto done;
    }

    /*
    Do low-level checks before initializing lifelines database layer,
    because lifelines database init traverses btree for user options
    and translation tables, and here we check the infrastructure of
    the btree itself.
    */
    if (todo.check_dbstructure || allchecks) {
        if (!check_btree(BTR))
            goto done;
    }

    if (!init_lifelines_postdb()) {
        printf(_(qSbaddb));
        goto done;
    }
    printf(_("Checking %s"), dbname);
    puts("");

    /* all checks - if any new ones, have to update this */
    if (allchecks) {
        todo.check_indis=todo.check_fams=todo.check_sours=TRUE;
        todo.check_evens=todo.check_othes=TRUE;
        todo.find_ghosts=TRUE;
    }

    if (todo.find_ghosts || todo.fix_ghosts)
        check_ghosts();


    if (!(bwrite(BTR))) {
        todo.fix_alter_pointers = FALSE;
        todo.fix_ghosts = FALSE;
    }

    if (todo.check_indis
            || todo.check_fams
            || todo.check_sours
            || todo.check_evens
            || todo.check_othes) {
        check_and_fix_records();
    }

    if (todo.check_missing_data_records) {
        check_missing_data_records();
    }

    report_results();

    closebtree(BTR);

    /* TODO: probably should call lldb_close, Perry 2005-10-07 */

    BTR = 0;
    returnvalue = 0;

done:
    return returnvalue;
}
Exemple #19
0
/*==========================================================
 * add_indi_by_edit -- Add new person to database by editing
 * (with user interaction)
 * returns addref'd record
 *========================================================*/
RECORD
add_indi_by_edit (RFMT rfmt)
{
	FILE *fp;
	RECORD indi0=0;
	NODE indi=0;
	STRING str, msg;
	BOOLEAN emp;
	XLAT ttmi = transl_get_predefined_xlat(MEDIN);

	if (readonly) {
		message(_(qSronlya));
		return NULL;
	}

/* Create person template for user to edit */

	if (!(fp = fopen(editfile, LLWRITETEXT)))
		return NULL;
	prefix_file_for_edit(fp);

	/* prefer useroption in this db */
	if ((str = getlloptstr("INDIREC", NULL)))
		fprintf(fp, "%s\n", str);
	else { /* default */
		fprintf(fp, "0 INDI\n1 NAME Fname/Surname\n1 SEX MF\n");
		fprintf(fp, "1 BIRT\n  2 DATE\n  2 PLAC\n");
		fprintf(fp, "1 DEAT\n  2 DATE\n  2 PLAC\n1 SOUR\n");
	}

/* Have user edit new person record */

	fclose(fp);
	do_edit();
	while (TRUE) {
		INT cnt;
		if (indi0) {
			release_record(indi0);
			indi0=0;
		}
		indi0 = file_to_record(editfile, ttmi, &msg, &emp);
		if (!indi0) {
			if (ask_yes_or_no_msg(msg, _(qSiredit))) {
				do_edit();
				continue;
			} 
			break;
		}
		indi = nztop(indi0);
		cnt = resolve_refn_links(indi);
		/* check validation & allow user to reedit if invalid */
		/* this is a showstopper, so alternative is to abort */
		if (!valid_indi_tree(indi, &msg, NULL)) {
			if (ask_yes_or_no_msg(msg, _(qSiredit))) {
				do_edit();
				continue;
			}
			release_record(indi0);
			indi0 = NULL;
			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];
			llstrncpyf(msgb, sizeof(msgb), uu8
				, get_unresolved_ref_error_string(cnt), cnt);
			if (ask_yes_or_no_msg(msgb, _(qSireditopt))) {
				write_indi_to_file_for_edit(indi, editfile, rfmt);
				do_edit();
				continue;
			}
		}
		break;
	}
	if (!indi0 || !ask_yes_or_no(_(qScfpadd))) {
		if (indi0) release_record(indi0);
		return NULL;
	}
	
	/* add the new record to the database */
	add_new_indi_to_db(indi0);

	msg_status(_(qSgdpadd), indi_to_name(nztop(indi0), 35));
	return indi0;
}
Exemple #20
0
/*=================================
 * init_lifelines_global -- Initialization options & misc. stuff
 *  This is called before first (or later) database opened
 *===============================*/
BOOLEAN
init_lifelines_global (STRING configfile, STRING * pmsg, void (*notify)(STRING db, BOOLEAN opening))
{
    STRING e;
    STRING dirvars[] = { "LLPROGRAMS", "LLREPORTS", "LLARCHIVES"
                         , "LLDATABASES",
                       };
    INT i;

    check_installation_path();

    /* request notification when options change */
    register_notify(&update_useropts);
    suppress_reload = TRUE;

    dbnotify_set(notify);

    if (!load_configs(configfile, pmsg)) {
        suppress_reload = FALSE;
        update_useropts(NULL);
        return FALSE;
    }

    pre_codesets_hook(); /* For MS-Windows user config of console codepages */

    /* now that codeset variables are set from config file, lets initialize codesets */
    /* although int_codeset can't be determined yet, we need GUI codeset for gettext */
    init_codesets();

    post_codesets_hook(); /* For Windows, link dynamically to gettext & iconv if available */


    /* until we have an internal codeset (which is until we open a database)
    we want output in display codeset */
    llgettext_init(PACKAGE, gui_codeset_out);

    /* read available translation tables */
    transl_load_all_tts();
    /* set up translations (for first time, will do it again after
    loading config table, and then again after loading database */
    transl_load_xlats();

    /* check if any directories not specified, and try environment
    variables, and default to "." */
    for (i=0; i<ARRSIZE(dirvars); ++i) {
        STRING str = getenv(dirvars[i]);
        if (!str)
            str = ".";
        setoptstr_fallback(dirvars[i], str);
    }
    /* also check environment variable for editor */
    {
        STRING str = getenv("LLEDITOR");
        if (!str)
            str = environ_determine_editor(PROGRAM_LIFELINES);
        setoptstr_fallback("LLEDITOR", str);
    }
    /* editor falls back to platform-specific default */
    e = getlloptstr("LLEDITOR", NULL);
    /* configure tempfile & edit command */
    editfile = environ_determine_tempfile();
    if (!editfile) {
        *pmsg = strsave("Error creating temp file");
        return FALSE;
    }
    editfile = strsave(editfile );
    editstr = (STRING) stdalloc(strlen(e) + strlen(editfile) + 2);
    sprintf(editstr, "%s %s", e, editfile);
    set_usersort(custom_sort);
    suppress_reload = FALSE;
    update_useropts(0);

    /* Finnish always uses custom character sets */
    if (opt_finnish ) {
        opt_mychar = TRUE;
        mych_set_table(ISO_Latin1);
    }


    return TRUE;
}
Exemple #21
0
/*==================================================
 * post_codesets_hook -- code to run just after initializing codesets
 * For Windows, link dynamically to gettext & iconv if available
 *================================================*/
static void
post_codesets_hook (void)
{
    init_win32_gettext_shim();
    init_win32_iconv_shim(getlloptstr("iconv.path",""));
}
Exemple #22
0
/*==================================
 * main -- Main routine of LifeLines
 *================================*/
int
main (int argc, char **argv)
{
	extern char *optarg;
	extern int optind;
	char * msg;
	int c;
	BOOLEAN ok=FALSE;
	STRING dbrequested=NULL; /* database (path) requested */
	STRING dbused=NULL; /* database (path) found */
	BOOLEAN forceopen=FALSE, lockchange=FALSE;
	char lockarg = 0; /* option passed for database lock */
	INT alteration=0;
	LIST exprogs=NULL;
	TABLE exargs=NULL;
	STRING progout=NULL;
	BOOLEAN graphical=TRUE;
	STRING configfile=0;
	STRING crashlog=0;
	int i=0;

	/* initialize all the low-level library code */
	init_stdlib();

#if HAVE_SETLOCALE
	/* initialize locales */
	setlocale(LC_ALL, "");
#endif /* HAVE_SETLOCALE */
	
	/* capture user's default codeset */
	ext_codeset = strsave(ll_langinfo());
	/* TODO: We can use this info for default conversions */

#if ENABLE_NLS
	/* setup gettext translation */
	ll_bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
#endif

	save_original_locales();
	load_usage();

	/* handle conventional arguments --version and --help */
	/* needed for help2man to synthesize manual pages */
	for (i=1; i<argc; ++i) {
		if (!strcmp(argv[i], "--version")
			|| !strcmp(argv[i], "-v")) {
			print_version("llexec");
			return 0;
		}
		if (!strcmp(argv[i], "--help")
			|| !strcmp(argv[i], "-h")
			|| !strcmp(argv[i], "-?")) {
			print_usage();
			return 0;
		}
	}

	/* Parse Command-Line Arguments */
	opterr = 0;	/* turn off getopt's error message */
	while ((c = getopt(argc, argv, "adkrwil:fntc:Fu:x:o:zC:I:vh?")) != -1) {
		switch (c) {
		case 'c':	/* adjust cache sizes */
			while(optarg && *optarg) {
				if(isasciiletter((uchar)*optarg) && isupper((uchar)*optarg))
					*optarg = tolower((uchar)*optarg);
				if(*optarg == 'i') {
					INT icsz_indi=0;
					sscanf(optarg+1, "%ld,%ld", &csz_indi, &icsz_indi);
				}
				else if(*optarg == 'f') {
					INT icsz_fam=0;
					sscanf(optarg+1, "%ld,%ld", &csz_fam, &icsz_fam);
				}
				else if(*optarg == 's') {
					INT icsz_sour=0;
					sscanf(optarg+1, "%ld,%ld", &csz_sour, &icsz_sour);
				}
				else if(*optarg == 'e') {
					INT icsz_even=0;
					sscanf(optarg+1, "%ld,%ld", &csz_even, &icsz_even);
				}
				else if((*optarg == 'o') || (*optarg == 'x')) {
					INT icsz_othr=0;
					sscanf(optarg+1, "%ld,%ld", &csz_othr, &icsz_othr);
				}
				optarg++;
				while(*optarg && isdigit((uchar)*optarg)) optarg++;
				if(*optarg == ',') optarg++;
				while(*optarg && isdigit((uchar)*optarg)) optarg++;
			}
			break;
#ifdef FINNISH
# ifdef FINNISHOPTION
		case 'F':	/* Finnish sorting order [toggle] */
			opt_finnish = !opt_finnish;
			/*
			TO DO - need to mark Finnish databases, as 
			name records are not interoperable, because of
			different soundex encoding
			2001/02/17, Perry Rapp
			*/
			break;
# endif
#endif
		case 'a':	/* debug allocation */
			alloclog = TRUE;
			break;
		case 'd':	/* debug = no signal catchers */
			debugmode = TRUE;
			break;
		case 'k':	/* don't show key values */
			keyflag = FALSE;
			break;
		case 'r':	/* request for read only access */
			readonly = TRUE;
			break;
		case 'w':	/* request for write access */
			writeable = TRUE;
			break;
		case 'i': /* immutable access */
			immutable = TRUE;
			readonly = TRUE;
			break;
		case 'l': /* locking switch */
			lockchange = TRUE;
			lockarg = *optarg;
			break;
		case 'f':	/* force database open in all cases */
			forceopen = TRUE;
			break;
		case 'n':	/* use non-traditional family rules */
			traditional = FALSE;
			break;
		case 't': /* show lots of trace statements for debugging */
			prog_trace = TRUE;
			break;
		case 'x': /* execute program */
			if (!exprogs) {
				exprogs = create_list2(LISTDOFREE);
			}
			push_list(exprogs, strdup(optarg ? optarg : ""));
			break;
		case 'I': /* program arguments */
			{
				STRING optname=0, optval=0;
				parse_arg(optarg, &optname, &optval);
				if (optname && optval) {
					if (!exargs) {
						exargs = create_table_str();
					}
					insert_table_str(exargs, optname, optval);
				}
				strfree(&optname);
				strfree(&optval);
			}
			break;
		case 'o': /* output directory */
			progout = optarg;
			break;
		case 'z': /* nongraphical box */
			graphical = FALSE;
			break;
		case 'C': /* specify config file */
			configfile = optarg;
			break;
		case 'v': /* show version */
			showversion = TRUE;
			goto usage;
			break;
		case 'h': /* show usage */
		case '?': /* show usage */
			showversion = TRUE;
			showusage = TRUE;
			goto usage;
			break;
		}
	}

prompt_for_db:

	/* catch any fault, so we can close database */
	if (debugmode)
		stdstring_hardfail();
	else
		set_signals();

	platform_init();
	set_displaykeys(keyflag);
	/* initialize options & misc. stuff */
	llgettext_set_default_localedir(LOCALEDIR);
	if (!init_lifelines_global(configfile, &msg, &main_db_notify)) {
		llwprintf("%s", msg);
		goto finish;
	}
	/* setup crashlog in case init_screen fails (eg, bad menu shortcuts) */
	crashlog = getlloptstr("CrashLog_llexec", NULL);
	if (!crashlog) { crashlog = "Crashlog_llexec.log"; }
	crash_setcrashlog(crashlog);
	init_interpreter(); /* give interpreter its turn at initialization */

	/* Validate Command-Line Arguments */
	if ((readonly || immutable) && writeable) {
		llwprintf(_(qSnorwandro));
		goto finish;
	}
	if (forceopen && lockchange) {
		llwprintf(_(qSnofandl));
		goto finish;
	}
	if (lockchange && lockarg != 'y' && lockarg != 'n') {
		llwprintf(_(qSbdlkar));
		goto finish;
	}
	if (forceopen)
		alteration = 3;
	else if (lockchange) {
		if (lockarg == 'y')
			alteration = 2;
		else
			alteration = 1;
	}
	c = argc - optind;
	if (c > 1) {
		showusage = TRUE;
		goto usage;
	}

	/* Open database, prompting user if necessary */
	if (1) {
		STRING errmsg=0;
		if (!alldone && c>0) {
			dbrequested = strsave(argv[optind]);
		} else {
			strupdate(&dbrequested, "");
		}
		if (!select_database(dbrequested, alteration, &errmsg)) {
			if (errmsg) {
				llwprintf(errmsg);
			}
			alldone = 0;
			goto finish;
		}
	}

	/* Start Program */
	if (!init_lifelines_postdb()) {
		llwprintf(_(qSbaddb));
		goto finish;
	}
	/* does not use show module */
	/* does not use browse module */
	if (exargs) {
		set_cmd_options(exargs);
		release_table(exargs);
		exargs = 0;
	}
	if (exprogs) {
		BOOLEAN picklist = FALSE;
		BOOLEAN timing = FALSE;
		interp_main(exprogs, progout, picklist, timing);
		destroy_list(exprogs);
	} else {
		/* TODO: prompt for report filename */
	}
	/* does not use show module */
	/* does not use browse module */
	ok=TRUE;

finish:
	/* we free this not because we care so much about these tiny amounts
	of memory, but to ensure we have the memory management right */
	/* strfree frees memory & nulls pointer */
	if (dbused) strfree(&dbused);
	strfree(&dbrequested);
	strfree(&readpath_file);
	shutdown_interpreter();
	close_lifelines();
	shutdown_ui(!ok);
	if (alldone == 2)
		goto prompt_for_db; /* changing databases */
	termlocale();
	strfree(&ext_codeset);

usage:
	/* Display Version and/or Command-Line Usage Help */
	if (showversion) { print_version("llexec"); }
	if (showusage) puts(usage_summary);

	/* Exit */
	return !ok;
}