/*========================================= * format_year -- Formats year part of date * yr: [IN] numeric year (0 for unknown) * yfmt: [IN] 0 - num, space * 1 - num, lead 0 * 2 - num, as is * * (No point in supporting negative numbers here, because parser only * picks up positive numbers.) * returns static buffer or 0 *=======================================*/ static STRING format_year (struct tag_dnum yr, INT yfmt) { static char scratch[7]; STRING p; INT yrval = yr.val; /* ignore complex years for now */ if (yrval > 9999 || yrval < 0) { switch(yfmt) { case 0: return " "; case 1: return "0000"; default: return NULL; } } if (yrval > 999 || yfmt == 2) { sprintf(scratch, "%ld", yrval); return scratch; } p = (yfmt==1 ? "000" : " "); if (yrval < 10) strcpy(scratch, p); else if (yrval < 100) llstrncpy(scratch, p, 2+1, uu8); else llstrncpy(scratch, p, 1+1, uu8); sprintf(scratch+strlen(scratch), "%ld", yrval); return scratch; }
/*================================================== * 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; }
/*================================================== * open_database -- open database * forceopen: [in] flag to override reader/writer protection * dbpath: [in] database path to open *================================================*/ BOOLEAN open_database (INT alteration, STRING dbpath, INT *lldberr) { LLDATABASE lldb = lldb_alloc(); BOOLEAN rtn = FALSE; char fpath[MAXPATHLEN]; /* tentatively copy paths into gedlib module versions */ strupdate(&readpath_file, lastpathname(dbpath)); llstrncpy(fpath, dbpath, sizeof(fpath), 0); expand_special_fname_chars(fpath, sizeof(fpath), uu8); strupdate(&readpath, fpath); if (f_dbnotify) (*f_dbnotify)(readpath, TRUE); rtn = open_database_impl(lldb, alteration, lldberr); if (!rtn) { /* open failed so clean up, preserve lldberr */ int myerr = *lldberr; lldb_close(&lldb); *lldberr = myerr; } def_lldb = lldb; return rtn; }
/*================================== * appendstr -- Append to string, subject to length limit * Advance target pointer and decrease length. * Safe to call after length goes to zero (nothing happens). * pdest: [I/O] output buffer * len: [I/O] bytes remaining in output * src: [IN] source to append * Created: 2000/11/29, Perry Rapp * NB: Need one byte for terminating zero, so len==1 is same as len==0. *================================*/ void appendstr (STRING * pdest, INT * len, int utf8, CNSTRING src) { int amount; *pdest[0]=0; /* so client doesn't have to initialize */ if (*len<=1) { *len=0; return; } llstrncpy(*pdest, src, *len, utf8); amount = strlen(*pdest); *pdest += amount; *len -= amount; if (*len<=1) *len=0; }
/*================================== * parse_arg -- Break argument into name & value * eg, parse_arg("main_indi=I3", &a, &b) * yields a="main_indi" and b="I3" * (a & b are newly allocated from heap) *================================*/ static void parse_arg (const char * optarg, char ** optname, char **optval) { const char * ptr; *optname = *optval = 0; for (ptr = optarg; *ptr; ++ptr) { if (*ptr == '=') { char * namebuff = 0; char * valbuff = 0; INT namelen = ptr - optarg; if (!namelen) return; namebuff = (char *)malloc(namelen+1); llstrncpy(namebuff, optarg, namelen+1, 0); *optname = namebuff; valbuff = strdup(ptr+1); *optval = valbuff; return; } } }
/*=================================================== * describe_dberror -- Describe database opening error * dberr: [in] error whose description is sought * buffer: [out] buffer for description * buflen: [in] size of buffer *=================================================*/ void describe_dberror (INT dberr, STRING buffer, INT buflen) { STRING b=buffer; INT n=buflen, u8=uu8; buffer[0]=0; if (dberr != BTERR_WRITER) llstrncpy(buffer, _("Database error: -- "), buflen, 0); switch (dberr) { case BTERR_NODB: llstrapps(b, n, u8, _("requested database does not exist.")); break; case BTERR_DBBLOCKEDBYFILE: llstrapps(b, n, u8, _("db directory is file, not directory.")); break; case BTERR_DBCREATEFAILED: llstrapps(b, n, u8, _("creation of new database failed.")); break; case BTERR_DBACCESS: llstrapps(b, n, u8, _("error accessing database directory.")); break; case BTERR_NOKEY: llstrapps(b, n, u8, _("no keyfile (directory does not appear to be a database).")); break; case BTERR_INDEX: llstrapps(b, n, u8, _("could not open, read or write an index file.")); break; case BTERR_KFILE: llstrapps(b, n, u8, _("could not open, read or write the key file.")); break; case BTERR_KFILE_ALTERDB: llstrapps(b, n, u8, _("could not open, read or write the key file (to alter database).")); break; case BTERR_BLOCK: llstrapps(b, n, u8, _("could not open, read or write a block file.")); break; case BTERR_LNGDIR: llstrapps(b, n, u8, _("name of database is too long.")); break; case BTERR_WRITER: llstrapps(b, n, u8, _("The database is already open for writing.")); break; case BTERR_LOCKED: llstrapps(b, n, u8, _("The database is locked (no readwrite access).")); break; case BTERR_UNLOCKED: llstrapps(b, n, u8, _("The database is unlocked.")); break; case BTERR_ILLEGKF: llstrapps(b, n, u8, _("keyfile is corrupt.")); break; case BTERR_ALIGNKF: llstrapps(b, n, u8, _("keyfile is wrong alignment.")); break; case BTERR_VERKF: llstrapps(b, n, u8, _("keyfile is wrong version.")); break; case BTERR_EXISTS: llstrapps(b, n, u8, _("Existing database found.")); break; case BTERR_READERS: llstrappf(b, n, u8 , _pl("The database is already opened for read access by %d user." , "The database is already opened for read access by %d users." , rdr_count) , rdr_count); break; case BTERR_BADPROPS: llstrapps(b, n, u8, _("Invalid properties set for new database")); break; default: llstrapps(b, n, u8, _("Undefined database error -- fix program.")); break; } }
/*============================ * brwsmenu_initialize -- set up menu arrays * screenheightx: [IN] user's terminal width * screenweidthx: [IN] user's terminal height * (After the first time, these are passed as 0, meaning use earlier values) * Created: 2001/01/28, Perry Rapp *==========================*/ void brwsmenu_initialize (INT screenheightx, INT screenwidthx) { INT i; INT scr; INT MenuRows, MenuCols, MenuSize; MenuItem ** MenuItems; struct BrowseScreenInfo * sinfo=0; char title[120]; /* defaults used by all browse screens except list browse */ INT MinRows=4; INT MaxRows=10; INT MinCols=1; INT MaxCols=7; INT MenuTop=0; INT MenuLeft=3; INT MenuWidth=0; if (screenheightx > 0) f_screenheight = screenheightx; if (screenwidthx > 0) { f_screenwidth = screenwidthx; f_cols = (f_screenwidth-5)/22; /* # of menu cols to start with */ } MenuWidth = f_screenwidth-6; MenuCols = f_cols; if (!f_initialized) { memset(f_BrowseScreenInfo, 0, sizeof(f_BrowseScreenInfo)); for (i=1; i<=MAX_SCREEN; i++) { /* DYNMENU dynmenu; dynmenu = get_screen_dynmenu(i); */ sinfo = &f_BrowseScreenInfo[i]; memset(sinfo, 0, sizeof(*sinfo)); sinfo->title = strsave(_("Missing title")); } f_initialized = TRUE; } scr = ONE_PER_SCREEN; sinfo = &f_BrowseScreenInfo[scr]; llstrncpy(title, _(qSttlindibrw), ARRSIZE(title), uu8); MenuRows = 8; MenuTop = f_screenheight-MenuRows - 3; MenuSize = ARRSIZE(f_MenuPerson)-1; MenuItems = f_MenuPerson; browsescreen_init(sinfo, title, MenuRows, MenuCols , MinCols, MaxCols , MinRows, MaxRows , MenuTop, MenuLeft, MenuWidth , MenuSize, MenuItems); scr = ONE_FAM_SCREEN; sinfo = &f_BrowseScreenInfo[scr]; llstrncpy(title, _(qSttlfambrw), ARRSIZE(title), uu8); MenuRows = 6; MenuTop = f_screenheight-MenuRows - 3; MenuSize = ARRSIZE(f_MenuFamily)-1; MenuItems = f_MenuFamily; browsescreen_init(sinfo, title, MenuRows, MenuCols , MinCols, MaxCols , MinRows, MaxRows , MenuTop, MenuLeft, MenuWidth , MenuSize, MenuItems); scr = TWO_PER_SCREEN; sinfo = &f_BrowseScreenInfo[scr]; llstrncpy(title, _(qSttl2perbrw), ARRSIZE(title), uu8); MenuRows = 5; MenuTop = f_screenheight-MenuRows - 3; MenuSize = ARRSIZE(f_Menu2Person)-1; MenuItems = f_Menu2Person; browsescreen_init(sinfo, title, MenuRows, MenuCols , MinCols, MaxCols , MinRows, MaxRows , MenuTop, MenuLeft, MenuWidth , MenuSize, MenuItems); scr = TWO_FAM_SCREEN; sinfo = &f_BrowseScreenInfo[scr]; llstrncpy(title, _(qSttl2fambrw), ARRSIZE(title), uu8); MenuRows = 5; MenuTop = f_screenheight-MenuRows - 3; MenuSize = ARRSIZE(f_Menu2Family)-1; MenuItems = f_Menu2Family; browsescreen_init(sinfo, title, MenuRows, MenuCols , MinCols, MaxCols , MinRows, MaxRows , MenuTop, MenuLeft, MenuWidth , MenuSize, MenuItems); scr = AUX_SCREEN; sinfo = &f_BrowseScreenInfo[scr]; llstrncpy(title, _(qSttlauxbrw), ARRSIZE(title), uu8); MenuRows = 4; MenuTop = f_screenheight-MenuRows - 3; MenuSize = ARRSIZE(f_MenuAux)-1; MenuItems = f_MenuAux; browsescreen_init(sinfo, title, MenuRows, MenuCols , MinCols, MaxCols , MinRows, MaxRows , MenuTop, MenuLeft, MenuWidth , MenuSize, MenuItems); /* TO DO: this is not used right now */ scr = LIST_SCREEN; sinfo = &f_BrowseScreenInfo[scr]; llstrncpy(title, _(qSttllstbrw), ARRSIZE(title), uu8); MenuRows = 13; MenuCols = 1; MenuSize = ARRSIZE(f_MenuListPersons)-1; MenuItems = f_MenuListPersons; MinRows = 5; MaxRows = 14; browsescreen_init(sinfo, title, MenuRows, MenuCols , MinCols, MaxCols , MinRows, MaxRows , MenuTop, MenuLeft, MenuWidth , MenuSize, MenuItems); if (!f_reloading) { register_brwsmenu_lang_callbacks(TRUE); } }
/*================================== * llstrset -- llstrncpy adopted to strset/strapp API * handles UTF-8 *================================*/ char * llstrsets (char *dest, size_t limit, int utf8, const char *src) { return llstrncpy(dest, src, limit, utf8); }