handle_viminfo_mark(garray_T *values, int force)
{
    bval_T	*vp = (bval_T *)values->ga_data;
    int		name;
    linenr_T	lnum;
    colnr_T	col;
    time_t	timestamp;
    xfmark_T	*fm = NULL;

    // Check the format:
    // |{bartype},{name},{lnum},{col},{timestamp},{filename}
    if (values->ga_len < 5
	    || vp[0].bv_type != BVAL_NR
	    || vp[1].bv_type != BVAL_NR
	    || vp[2].bv_type != BVAL_NR
	    || vp[3].bv_type != BVAL_NR
	    || vp[4].bv_type != BVAL_STRING)
	return;

    name = vp[0].bv_nr;
    if (name != '\'' && !VIM_ISDIGIT(name) && !ASCII_ISUPPER(name))
	return;
    lnum = vp[1].bv_nr;
    col = vp[2].bv_nr;
    if (lnum <= 0 || col < 0)
	return;
    timestamp = (time_t)vp[3].bv_nr;

    if (name == '\'')
    {
	if (vi_jumplist != NULL)
	{
	    if (vi_jumplist_len < JUMPLISTSIZE)
		fm = &vi_jumplist[vi_jumplist_len++];
	}
	else
	{
	    int idx;
	    int i;

	    // If we have a timestamp insert it in the right place.
	    if (timestamp != 0)
	    {
		for (idx = curwin->w_jumplistlen - 1; idx >= 0; --idx)
		    if (curwin->w_jumplist[idx].time_set < timestamp)
		    {
			++idx;
			break;
		    }
		// idx cannot be zero now
		if (idx < 0 && curwin->w_jumplistlen < JUMPLISTSIZE)
		    // insert as the oldest entry
		    idx = 0;
	    }
	    else if (curwin->w_jumplistlen < JUMPLISTSIZE)
		// insert as oldest entry
		idx = 0;
	    else
		idx = -1;

	    if (idx >= 0)
	    {
		if (curwin->w_jumplistlen == JUMPLISTSIZE)
		{
		    // Drop the oldest entry.
		    --idx;
		    vim_free(curwin->w_jumplist[0].fname);
		    for (i = 0; i < idx; ++i)
			curwin->w_jumplist[i] = curwin->w_jumplist[i + 1];
		}
		else
		{
		    // Move newer entries forward.
		    for (i = curwin->w_jumplistlen; i > idx; --i)
			curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
		    ++curwin->w_jumplistidx;
		    ++curwin->w_jumplistlen;
		}
		fm = &curwin->w_jumplist[idx];
		fm->fmark.mark.lnum = 0;
		fm->fname = NULL;
		fm->time_set = 0;
	    }
	}
    }
    else
    {
	int		idx;
	xfmark_T	*namedfm_p = get_namedfm();

	if (VIM_ISDIGIT(name))
	{
	    if (vi_namedfm != NULL)
		idx = name - '0' + NMARKS;
	    else
	    {
		int i;

		// Do not use the name from the viminfo file, insert in time
		// order.
		for (idx = NMARKS; idx < NMARKS + EXTRA_MARKS; ++idx)
		    if (namedfm_p[idx].time_set < timestamp)
			break;
		if (idx == NMARKS + EXTRA_MARKS)
		    // All existing entries are newer.
		    return;
		i = NMARKS + EXTRA_MARKS - 1;

		vim_free(namedfm_p[i].fname);
		for ( ; i > idx; --i)
		    namedfm_p[i] = namedfm_p[i - 1];
		namedfm_p[idx].fname = NULL;
	    }
	}
	else
	    idx = name - 'A';
	if (vi_namedfm != NULL)
	    fm = &vi_namedfm[idx];
	else
	    fm = &namedfm_p[idx];
    }

    if (fm != NULL)
    {
	if (vi_namedfm != NULL || fm->fmark.mark.lnum == 0
					  || fm->time_set < timestamp || force)
	{
	    fm->fmark.mark.lnum = lnum;
	    fm->fmark.mark.col = col;
	    fm->fmark.mark.coladd = 0;
	    fm->fmark.fnum = 0;
	    vim_free(fm->fname);
	    if (vp[4].bv_allocated)
	    {
		fm->fname = vp[4].bv_string;
		vp[4].bv_string = NULL;
	    }
	    else
		fm->fname = vim_strsave(vp[4].bv_string);
	    fm->time_set = timestamp;
	}
    }
}
handle_viminfo_mark(garray_T *values, int force)
{
    bval_T	*vp = (bval_T *)values->ga_data;
    int		name;
    linenr_T	lnum;
    colnr_T	col;
    time_t	timestamp;
    xfmark_T	*fm = NULL;

     
     
    if (values->ga_len < 5
	    || vp[0].bv_type != BVAL_NR
	    || vp[1].bv_type != BVAL_NR
	    || vp[2].bv_type != BVAL_NR
	    || vp[3].bv_type != BVAL_NR
	    || vp[4].bv_type != BVAL_STRING)
	return;

    name = vp[0].bv_nr;
    if (name != '\'' && !VIM_ISDIGIT(name) && !ASCII_ISUPPER(name))
	return;
    lnum = vp[1].bv_nr;
    col = vp[2].bv_nr;
    if (lnum <= 0 || col < 0)
	return;
    timestamp = (time_t)vp[3].bv_nr;

    if (name == '\'')
    {
	if (vi_jumplist != NULL)
	{
	    if (vi_jumplist_len < JUMPLISTSIZE)
		fm = &vi_jumplist[vi_jumplist_len++];
	}
	else
	{
	    int idx;
	    int i;

	     
	    if (timestamp != 0)
	    {
		for (idx = curwin->w_jumplistlen - 1; idx >= 0; --idx)
		    if (curwin->w_jumplist[idx].time_set < timestamp)
		    {
			++idx;
			break;
		    }
		 
		if (idx < 0 && curwin->w_jumplistlen < JUMPLISTSIZE)
		     
		    idx = 0;
	    }
	    else if (curwin->w_jumplistlen < JUMPLISTSIZE)
		 
		idx = 0;
	    else
		idx = -1;

	    if (idx >= 0)
	    {
		if (curwin->w_jumplistlen == JUMPLISTSIZE)
		{
		     
		    --idx;
		    vim_free(curwin->w_jumplist[0].fname);
		    for (i = 0; i < idx; ++i)
			curwin->w_jumplist[i] = curwin->w_jumplist[i + 1];
		}
		else
		{
		     
		    for (i = curwin->w_jumplistlen; i > idx; --i)
			curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
		    ++curwin->w_jumplistidx;
		    ++curwin->w_jumplistlen;
		}
		fm = &curwin->w_jumplist[idx];
		fm->fmark.mark.lnum = 0;
		fm->fname = NULL;
		fm->time_set = 0;
	    }
	}
    }
    else
    {
	int		idx;
	xfmark_T	*namedfm_p = get_namedfm();

	if (VIM_ISDIGIT(name))
	{
	    if (vi_namedfm != NULL)
		idx = name - '0' + NMARKS;
	    else
	    {
		int i;

		 
		 
		for (idx = NMARKS; idx < NMARKS + EXTRA_MARKS; ++idx)
		    if (namedfm_p[idx].time_set < timestamp)
			break;
		if (idx == NMARKS + EXTRA_MARKS)
		     
		    return;
		i = NMARKS + EXTRA_MARKS - 1;

		vim_free(namedfm_p[i].fname);
		for ( ; i > idx; --i)
		    namedfm_p[i] = namedfm_p[i - 1];
		namedfm_p[idx].fname = NULL;
	    }
	}
	else
	    idx = name - 'A';
	if (vi_namedfm != NULL)
	    fm = &vi_namedfm[idx];
	else
	    fm = &namedfm_p[idx];
    }

    if (fm != NULL)
    {
	if (vi_namedfm != NULL || fm->fmark.mark.lnum == 0
					  || fm->time_set < timestamp || force)
	{
	    fm->fmark.mark.lnum = lnum;
	    fm->fmark.mark.col = col;
	    fm->fmark.mark.coladd = 0;
	    fm->fmark.fnum = 0;
	    vim_free(fm->fname);
	    if (vp[4].bv_allocated)
	    {
		fm->fname = vp[4].bv_string;
		vp[4].bv_string = NULL;
	    }
	    else
		fm->fname = vim_strsave(vp[4].bv_string);
	    fm->time_set = timestamp;
	}
    }
}