Exemplo n.º 1
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);
}
Exemplo n.º 2
0
/*============================
 * mvcwaddnstr -- convert to GUI codeset & call mvwaddstr with length limit
 * Created: 2002/12/13 (Perry Rapp)
  *==========================*/
int
mvccwaddnstr (WINDOW *wp, int y, int x, const char *cp, int n)
{
	ZSTR zstr = zs_news(cp);
	int rtn=0;
	
	int_to_disp(zstr);

	if (zs_len(zstr) < (unsigned int)n) {
		rtn = mvwaddstr(wp, y, x, zs_str(zstr));
	} else {
		if (output_width(zstr) > (size_t)n) {
			STRING str = zs_str(zstr);
			/* We need to do length truncation correctly for UTF-8 output */
			/* #1) We need to not break UTF-8 multibytes */

			INT width=0;
			STRING prev = find_prev_char(&str[n-1], &width, str, gui8);
			width += (prev - str);
			zs_chop(zstr, width);

			/* #2) We should account for zero-width characters, eg, use wcwidth */
			/* Unfortunately, lifelines doesn't yet use wcwidth or config test it */
			/* TODO:
			config test for wcswidth
			and substitute Markus Kuhn's
			http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
			*/
		}
		rtn = mvwaddnstr(wp, y, x, zs_str(zstr), n);
	}
	zs_free(&zstr);
	return rtn;
}
Exemplo n.º 3
0
static void zram_free_page(struct zram *zram, size_t index)
{
	struct zram_meta *meta = zram->meta;
	unsigned long handle = meta->table[index].handle;
	u16 size = meta->table[index].size;

	if (unlikely(!handle)) {
		/*
		 * No memory is allocated for zero filled pages.
		 * Simply clear zero page flag.
		 */
		if (zram_test_flag(meta, index, ZRAM_ZERO)) {
			zram_clear_flag(meta, index, ZRAM_ZERO);
			zram->stats.pages_zero--;
		}
		return;
	}

	if (unlikely(size > max_zpage_size))
		zram->stats.bad_compress--;

	zs_free(meta->mem_pool, handle);

	if (size <= PAGE_SIZE / 2)
		zram->stats.good_compress--;

	zram_stat64_sub(zram, &zram->stats.compr_size,
			meta->table[index].size);
	zram->stats.pages_stored--;

	meta->table[index].handle = 0;
	meta->table[index].size = 0;
}
Exemplo n.º 4
0
/*====================================================
 * format_dbgsymtab_val -- Display one entry in symbol table
 *  This is part of the report language debugger
 *  key:   [IN]  name of current symbol
 *  val:   [IN]  value of current symbol
 *  sdata: [I/O] structure holding array of values & strings to display
 *==================================================*/
static void
format_dbgsymtab_val (STRING key, PVALUE val, struct dbgsymtab_s * sdata)
{
	ZSTR zval = describe_pvalue(val);
	STRING valstr = zs_str(zval);
	format_dbgsymtab_str(key, valstr, val, sdata);
	zs_free(&zval);
}
Exemplo n.º 5
0
/*============================
 * mvcwaddstr -- convert to GUI codeset & call mvwaddstr
 * Created: 2002/12/03 (Perry Rapp)
 * TODO: Convert all calls of this to call mvccuwaddstr (or mvccwaddnstr) !
 *==========================*/
int
mvccwaddstr (WINDOW *wp, int y, int x, const char *cp)
{
	ZSTR zstr = zs_news(cp);
	int rtn;
	int_to_disp(zstr);
	rtn = mvwaddstr(wp, y, x, zs_str(zstr));
	zs_free(&zstr);
	return rtn;
}
Exemplo n.º 6
0
/*============================
 * vccprintf -- vprintf with codeset convert from internal to GUI
 * Created: 2002/12/03 (Perry Rapp)
 *==========================*/
int
vccprintf (const char *fmt, va_list args)
{
	int rtn;
	ZSTR zstr = zs_newvf(fmt, args);
	int_to_disp(zstr);
	rtn = printf(zs_str(zstr));
	zs_free(&zstr);
	return rtn;
}
Exemplo n.º 7
0
/*============================
 * vccwprintw -- vwprintw with codeset convert from internal to GUI
 * Created: 2002/12/03 (Perry Rapp)
 *==========================*/
int
vccwprintw (WINDOW *wp, const char *fmt, va_list args)
{
	ZSTR zstr = zs_newvf(fmt, args);
	int rtn;
	int_to_disp(zstr);
	rtn = waddstr(wp, zs_str(zstr));
	zs_free(&zstr);
	return rtn;
}
Exemplo n.º 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;
}
Exemplo n.º 9
0
/*====================================================
 * format_dbgsymtab_val -- Display one entry in symbol table
 *  This is part of the report language debugger
 *  key:   [IN]  name of current symbol
 *  valstr:   [IN]  string to display for current value
 *  val:   [IN]  value of current symbol (or NULL if none applicable)
 *  sdata: [I/O] structure holding array of values & strings to display
 *==================================================*/
static void
format_dbgsymtab_str (STRING key, STRING valstr, PVALUE val, struct dbgsymtab_s * sdata)
{
	ZSTR zline = zs_newn(80);
	ASSERT(sdata->current < sdata->count);
	zs_setf(zline, "%s: %s", key, valstr);
	sdata->displays[sdata->current] = strsave(zs_str(zline));
	sdata->values[sdata->current] = val;
	++sdata->current;
	zs_free(&zline);
}
Exemplo n.º 10
0
/*==========================================
 * do_format_date -- Do general date formatting
 * str - raw string containing a date
 *  dfmt; [IN]  day format code (see format_day function below)
 *  mfmt: [IN]  month format code (see format_month function below)
 *  yfmt: [IN]  year format code (see format_year function below)
 *  sfmt: [IN]  combining code (see format_ymd function below)
 *  efmt: [IN]  era format (see format_eratime function below)
 * cmplx - 0 is year only, 1 is complex, including
 *         date modifiers, ranges, and/or double-dating
 * Returns static buffer
 *========================================*/
STRING
do_format_date (STRING str, INT dfmt, INT mfmt,
             INT yfmt, INT sfmt, INT efmt, INT cmplx)
{
	/* TODO: get rid of this function, and have callers call do_zformat_date */
	ZSTR zstr = do_zformat_date(str, dfmt, mfmt, yfmt, sfmt, efmt, cmplx);
	static char buffer[100];
	llstrsets(buffer, sizeof(buffer), uu8, zs_str(zstr));
	zs_free(&zstr);
	return buffer;
}
Exemplo n.º 11
0
/*===================================================
 * translate_string -- Translate string via XLAT
 *  ttm:     [IN]  tranmapping
 *  in:      [IN]  in string
 *  out:     [OUT] string
 *  maxlen:  [OUT] max len of out string
 * Output string is limited to max length via use of
 * add_char & add_string.
 *=================================================*/
void
translate_string (XLAT ttm, CNSTRING in, STRING out, INT maxlen)
{
    ZSTR zstr=0;
    if (!in || !in[0]) {
        out[0] = 0;
        return;
    }
    zstr = translate_string_to_zstring(ttm, in);
    llstrsets(out, maxlen, uu8, zs_str(zstr));
    zs_free(&zstr);
}
Exemplo n.º 12
0
/*============================
 * wgetccnstr -- wgetnstr with codeset convert from GUI to internal
 * Created: 2002/12/03 (Perry Rapp)
 *==========================*/
int
wgetccnstr (WINDOW *wp, char *cp, int n)
{
	ZSTR zstr=0;
/* TODO: Need Win32-specific code here to handle Unicode input on NT family */
	int rtn = wgetnstr(wp, (char *)cp, n);
	zstr = zs_news(cp);
	disp_to_int(zstr);
	llstrsets(cp, n, uu8, zs_str(zstr));
	zs_free(&zstr);
	return rtn;
}
Exemplo n.º 13
0
/*==========================================================
 * transl_get_description -- Fetch description of a translation
 *  eg, "3 steps with iconv(UTF-8, CP1252)"
 * Created: 2002/12/13 (Perry Rapp)
 *========================================================*/
ZSTR
transl_get_description (XLAT xlat)
{
    ZSTR zstr = xlat_get_description(xlat);
    INT index = xl_get_uparam(xlat)-1;
    struct legacytt_s * legtt = (index>=0 ? &legacytts[index] : NULL);
    if (legtt && legtt->tt) {
        ZSTR zdesc = get_trantable_desc(legtt->tt);
        /* TRANSLATORS: db internal translation table note for tt menu */
        zs_appf(zstr, _(" (dbint tt: %s)"), zs_str(zdesc));
        zs_free(&zdesc);
    }

    return zstr;
}
Exemplo n.º 14
0
/*=======================================================
 * annotate_node -- Alter a node by
 *  expanding refns (eg, "@S25@" to "<1850.Census>")
 *  annotating pointers (eg, "@I1@" to "@I1@ {{ John/SMITH }}")
 * Used during editing
 *=====================================================*/
static void
annotate_node (NODE node, BOOLEAN expand_refns, BOOLEAN annotate_pointers, RFMT rfmt)
{
	STRING key=0;
	RECORD rec=0;

	key = value_to_xref(nval(node));
	if (!key) return;
	
	rec = key_possible_to_record(key, *key);
	if (!rec) return;
	
	if (expand_refns) {
		NODE refn = REFN(nztop(rec));
		char buffer[60];
		/* if there is a REFN, and it fits in our buffer,
		and it doesn't have any (confusing) > in it */
		if (refn && nval(refn) && !strchr(nval(refn), '>')
			&& strlen(nval(refn))<=sizeof(buffer)-3) {
			/* then replace, eg, @S25@, with, eg, <1850.Census> */
			buffer[0]=0;
			strcpy(buffer, "<");
			strcat(buffer, nval(refn));
			strcat(buffer, ">");
			stdfree(nval(node));
			nval(node) = strsave(buffer);
		}
	}

	if (annotate_pointers) {
		STRING str = generic_to_list_string(nztop(rec), key, 60, ", ", rfmt, FALSE);
		ZSTR zstr = zs_news(nval(node));
		zs_apps(zstr, " {{");
		zs_apps(zstr, str);
		zs_apps(zstr, " }}");
		stdfree(nval(node));
		nval(node) = strsave(zs_str(zstr));
		zs_free(&zstr);
	}
}
Exemplo n.º 15
0
/*=============================================+
 * prog_var_error_zstr -- Report a run time program error
 *  node:  [IN]  current parse node
 *  stab:  [IN]  current symbol table (lexical scope)
 *  arg:   [IN]  if non-null, parse node of troublesome argument
 *  val:   [IN]  if non-null, PVALUE of troublesome argument
 *  zstr:  [IN]  message
 *
 * Inline debugger is implemented here
 * See vprog_error
 * Created: 2002/02/17, Perry Rapp
 *============================================*/
static void
prog_var_error_zstr (PNODE node, SYMTAB stab, PNODE arg, PVALUE val, ZSTR zstr)
{
	STRING choices[5];
	INT rtn=0;
	SYMTAB curstab = stab; /* currently displayed symbol table */
	INT nlevels=0; /* number frames on callstack */
	INT curlevel=0; /* 0 is lowest */

	ASSERT(zstr);

	if (val) {
		ZSTR zval = describe_pvalue(val);
		zs_appf(zstr, " (value: %s)", zs_str(zval));
	} else if (arg) {
		INT max=40 + zs_len(zstr); /* not too much argument description */
		/* arg isn't evaluated, but describe will at least give its type */
		zs_apps(zstr, " (arg: ");
		describe_pnode(arg, zstr, max);
		zs_apps(zstr, ")");
	}
	prog_error(node, zs_str(zstr));
	zs_free(&zstr);

	if (dbg_mode != -99 && dbg_mode != 3) {
		INT ch = 0;
		while (!(ch=='d' || ch=='q'))
			ch = rptui_prompt_stdout(_("Enter d for debugger, q to quit"));
		if (ch == 'q')
			dbg_mode = -99;
	}

	/* call stack size & location */
	nlevels = count_symtab_ancestors(stab) + 1;
	curlevel = 0;

	/* report debugger loop */
	while (dbg_mode != -99) {
		ZSTR zstr=zs_new();
		INT n=0;
		/* 0: display local variable(s) */
		n = (curstab->tab ? get_table_count(curstab->tab) : 0);
		zs_setf(zstr, _pl("Display local (%d var)",
			"Display locals (%d vars)", n), n);
		zs_appf(zstr, " [%s]", curstab->title);
		choices[0] = strsave(zs_str(zstr));
		/* 1: display global variables */
		n = (globtab->tab ? get_table_count(globtab->tab) : 0);
		zs_setf(zstr, _pl("Display global (%d var)",
			"Display globals (%d vars)", n), n);
		choices[1] = strsave(zs_str(zstr));
		/* 2: up call stack */
		n = nlevels - curlevel - 1;
		zs_setf(zstr, _pl("Call stack has %d higher level", "Call stack has %d higher levels", n), n);
		zs_apps(zstr, ". ");
		if (n > 0) {
			zs_apps(zstr, _(" Go up one level"));
			zs_appf(zstr, "(%s)", curstab->parent->title);
		}
		choices[2] = strsave(zs_str(zstr));
		/* 3: down call stack */
		n = curlevel;
		zs_setf(zstr, _pl("Call stack has %d lower level", "Call stack has %d lower levels", n), n);
		zs_apps(zstr, ". ");
		if (n > 0) {
			CNSTRING title = get_symtab_ancestor(stab, n-1)->title;
			zs_apps(zstr, _(" Go down one level"));
			zs_appf(zstr, "(%s)", title);
		}
		choices[3] = strsave(zs_str(zstr));
		/* quit */
		choices[4] = strsave(_("Quit debugger"));
dbgloop:
		rtn = rptui_choose_from_array(_("Report debugger"), ARRSIZE(choices), choices);
		if (rtn == 4 || rtn == -1) {
			dbg_mode = -99;
		} else if (rtn == 0) {
			disp_symtab(_("Local variables"), curstab);
			goto dbgloop;
		} else if (rtn == 1) {
			disp_symtab(_("Global variables"), globtab);
			goto dbgloop;
		} else if (rtn == 2) {
			if (curlevel+1 < nlevels) {
				curstab = curstab->parent;
				++curlevel;
				ASSERT(curstab);
			}
		} else if (rtn == 3) {
			if (curlevel > 0) {
				curstab = get_symtab_ancestor(stab, curlevel-1);
				--curlevel;
				ASSERT(curstab);
			}
		}
		zs_free(&zstr);
		free_array_strings(ARRSIZE(choices), choices);
	}
}
Exemplo n.º 16
0
int main (int argc, char *argv[])
{
  ZIPstream *zstream = NULL;
  ZIPentry *zentry = NULL;

  uint64_t buffersize = 0;
  ssize_t writestatus;

  time_t now;
  int method = ZS_DEFLATE;
  int fd;
  int idx;

  if ( argc < 2 )
    {
      fprintf (stderr, "zipexample: write a ZIP archive to stdout from memory buffer\n");
      fprintf (stderr, "Usage: zipexample [-S] [-D] > output.zip\n");
      fprintf (stderr, "  -S  Store archive entries\n");
      fprintf (stderr, "  -D  Deflate archive entries\n");
      fprintf (stderr, "\n");
      fprintf (stderr, "One of -S or -D is required, make sure to redirect stdout.");
      fprintf (stderr, "\n");
      return 0;
    }

  /* Loop through input arguments and process options */
  for ( idx=1; idx < argc; idx++ )
    {
      if ( ! strncmp (argv[idx], "-S", 2) )
        {
          method = ZS_STORE;
          fprintf (stderr, "Storing archive entries, no compression\n");
          continue;
        }
      else if ( ! strncmp (argv[idx], "-D", 2) )
        {
          method = ZS_DEFLATE;
          fprintf (stderr, "Deflating archive entries, no compression\n");
          continue;
        }
    }

  /* Set output stream to stdout */
  fd = fileno (stdout);

  /* Initialize ZIP container, skip options */
  if ( (zstream = zs_init (fd, NULL)) == NULL )
    {
      fprintf (stderr, "Error initializing ZIP archive\n");
      return 1;
    }

  buffersize = strlen (buffer);
  now = time(NULL);

  /* Write entry containing buffer contents */
  zentry = zs_writeentry (zstream, (unsigned char *)buffer, buffersize,
                          "Leon.txt", now, method, &writestatus);

  if ( zentry == NULL )
    {
      fprintf (stderr, "Error adding entry to output ZIP (writestatus: %lld)\n",
               (long long int) writestatus);
      return 1;
    }

  fprintf (stderr, "Added %s: %lld -> %lld (%.1f%%)\n",
           zentry->Name,
           (long long int) zentry->UncompressedSize,
           (long long int) zentry->CompressedSize,
           (100.0 * zentry->CompressedSize / zentry->UncompressedSize));

  /* Write another entry containing the same buffer contents */
  zentry = zs_writeentry (zstream, (unsigned char *)buffer, buffersize,
                          "Deckard.txt", now, method, &writestatus);

  if ( zentry == NULL )
    {
      fprintf (stderr, "Error adding entry to output ZIP (writestatus: %lld)\n",
               (long long int) writestatus);
      return 1;
    }

  fprintf (stderr, "Added %s: %lld -> %lld (%.1f%%)\n",
           zentry->Name,
           (long long int) zentry->UncompressedSize,
           (long long int) zentry->CompressedSize,
           (100.0 * zentry->CompressedSize / zentry->UncompressedSize));

  /* Many more files/entries can be added to the ZIP archive ... */

  /* Finish ZIP archive */
  if ( zs_finish (zstream, &writestatus) )
    {
      fprintf (stderr, "Error finishing ZIP archive (writestatus: %lld)\n",
               (long long int) writestatus);
      return 1;
    }

  fprintf (stderr, "Success, created archive with %d entries\n",
           zstream->EntryCount);

  /* Cleanup */
  zs_free (zstream);

  return 0;
}
Exemplo n.º 17
0
/*========================================+
 * poutput -- Output string in current mode
 *=======================================*/
void
poutput (STRING str, BOOLEAN *eflg)
{
	STRING p;
	ZSTR zstr = 0;
	INT c, len;
	XLAT ttmr = transl_get_predefined_xlat(MINRP);
	if (!str || (len = strlen(str)) <= 0) return;
	zstr = translate_string_to_zstring(ttmr, str);
	str = zs_str(zstr);
	if ((len = strlen(str)) <= 0)
		goto exit_poutput;
	if (!Poutfp) {
		if (!request_file(eflg))
			goto exit_poutput;
		setbuf(Poutfp, NULL);
	}
	switch (outputmode) {
	case UNBUFFERED:
		fwrite(str, len, 1, Poutfp);
		adjust_cols(str);
		goto exit_poutput;
	case BUFFERED:
		if (len >= 1024) {
			fwrite(linebuffer, linebuflen, 1, Poutfp);
			fwrite(str, len, 1, Poutfp);
			linebuflen = 0;
			bufptr = (STRING)linebuffer;
			adjust_cols(str);
			goto exit_poutput;
		}
		if (len + linebuflen >= 1024) {
			fwrite(linebuffer, linebuflen, 1, Poutfp);
			linebuflen = 0;
			bufptr = (STRING)linebuffer;
		}
		linebuflen += len;
		while ((c = *bufptr++ = *str++)) {
			if (c == '\n')
				curcol = 1;
			else
				curcol++;
		}
		--bufptr;
		goto exit_poutput;
	case PAGEMODE:
		p = pagebuffer + (currow - 1)*__cols + curcol - 1;
		while ((c = *str++)) {
			if (c == '\n') {
				curcol = 1;
				currow++;
				p = pagebuffer + (currow - 1)*__cols;
			} else {
				if (curcol <= __cols && currow <= __rows)
					*p++ = c;
				curcol++;
			}
		}
		goto exit_poutput;
	default:
		FATAL();
	}
exit_poutput:
	zs_free(&zstr);
}
Exemplo n.º 18
0
/*==========================================
 * do_zformat_date
 * See description above for do_format_date
 * (Except this returns alloc'd ZSTR
 *========================================*/
static ZSTR
do_zformat_date (STRING str, INT dfmt, INT mfmt,
             INT yfmt, INT sfmt, INT efmt, INT cmplx)
{
	STRING smo, syr;
	static char daystr[3];
	GDATEVAL gdv = 0;
	ZSTR zstr=zs_newn(40);
	
	if (!str) return zstr;

	initialize_if_needed();

	if (sfmt==12) {
		/* This is what used to be the shrt flag */
		zs_free(&zstr);
		return zshorten_date(str);
	}
	if (sfmt==14) {
		zs_sets(zstr, str);
		return zstr;
	}
	if (!cmplx) {
		/* simple */
		gdv = extract_date(str);
		if (gdv->valid == GDV_V_PHRASE) {
			/* GEDCOM date phrases (parenthesized) shown "as is" */
			return zs_news(gdv->text);
		}
		format_day(gdv->date1.day, dfmt, daystr);
		smo = format_month(gdv->date1.calendar, gdv->date1.month, mfmt);
		syr = format_year(gdv->date1.year, yfmt);
		format_ymd(zstr, syr, smo, daystr, sfmt);
		format_eratime(zstr, gdv->date1.eratime, efmt);
		if (gdv->date1.calendar) {
			format_cal(zstr, gdv->date1.calendar);
		}
		free_gdateval(gdv);
		return zstr;
	} else {
		ZSTR zstr2 = zs_newn(40);
		ZSTR zstr3=0;
		/* complex (include modifier words) */
		gdv = extract_date(str);
		if (gdv->valid == GDV_V_PHRASE) {
			/* GEDCOM date phrases (parenthesized) shown "as is" */
			return zs_news(gdv->text);
		}
		format_day(gdv->date1.day, dfmt, daystr);
		smo = format_month(gdv->date1.calendar, gdv->date1.month, mfmt);
		syr = (gdv->date1.year.str ? gdv->date1.year.str 
			: format_year(gdv->date1.year, yfmt));
		format_ymd(zstr, syr, smo, daystr, sfmt);
		format_eratime(zstr, gdv->date1.eratime, efmt);
		if (gdv->date1.calendar) {
			format_cal(zstr, gdv->date1.calendar);
		}
		if (gdateval_isdual(gdv)) {
			/* build 2nd date string into ymd2 */
			format_day(gdv->date2.day, dfmt, daystr);
			smo = format_month(gdv->date2.calendar, gdv->date2.month, mfmt);
			syr = (gdv->date2.year.str ? gdv->date2.year.str 
				: format_year(gdv->date2.year, yfmt));
			format_ymd(zstr2, syr, smo, daystr, sfmt);
			format_eratime(zstr2, gdv->date2.eratime, efmt);
			if (gdv->date2.calendar) {
				format_cal(zstr2, gdv->date2.calendar);
			}
		}
		zstr3 = format_complex(gdv, cmplx, zs_str(zstr), zs_str(zstr2));
		zs_free(&zstr);
		zs_free(&zstr2);
		free_gdateval(gdv);
		return zstr3;
	}
}
Exemplo n.º 19
0
/*=================================================
 * 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;
}