mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.3871: list.c contains code for dict and blob
Problem: List.c contains code for dict and blob. Solution: Refactor to put code where it belongs. (Yegappan Lakshmanan, closes #9386)
This commit is contained in:
committed by
Bram Moolenaar
parent
1aeccdb464
commit
f973eeb491
184
src/strings.c
184
src/strings.c
@@ -764,7 +764,6 @@ concat_str(char_u *str1, char_u *str2)
|
||||
}
|
||||
|
||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||
|
||||
/*
|
||||
* Return string "str" in ' quotes, doubling ' characters.
|
||||
* If "str" is NULL an empty string is assumed.
|
||||
@@ -809,6 +808,185 @@ string_quote(char_u *str, int function)
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count the number of times "needle" occurs in string "haystack". Case is
|
||||
* ignored if "ic" is TRUE.
|
||||
*/
|
||||
long
|
||||
string_count(char_u *haystack, char_u *needle, int ic)
|
||||
{
|
||||
long n = 0;
|
||||
char_u *p = haystack;
|
||||
char_u *next;
|
||||
|
||||
if (p == NULL || needle == NULL || *needle == NUL)
|
||||
return 0;
|
||||
|
||||
if (ic)
|
||||
{
|
||||
size_t len = STRLEN(needle);
|
||||
|
||||
while (*p != NUL)
|
||||
{
|
||||
if (MB_STRNICMP(p, needle, len) == 0)
|
||||
{
|
||||
++n;
|
||||
p += len;
|
||||
}
|
||||
else
|
||||
MB_PTR_ADV(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
while ((next = (char_u *)strstr((char *)p, (char *)needle)) != NULL)
|
||||
{
|
||||
++n;
|
||||
p = next + STRLEN(needle);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a typval_T of the first character of "input" and store it in "output".
|
||||
* Return OK or FAIL.
|
||||
*/
|
||||
static int
|
||||
copy_first_char_to_tv(char_u *input, typval_T *output)
|
||||
{
|
||||
char_u buf[MB_MAXBYTES + 1];
|
||||
int len;
|
||||
|
||||
if (input == NULL || output == NULL)
|
||||
return FAIL;
|
||||
|
||||
len = has_mbyte ? mb_ptr2len(input) : 1;
|
||||
STRNCPY(buf, input, len);
|
||||
buf[len] = NUL;
|
||||
output->v_type = VAR_STRING;
|
||||
output->vval.v_string = vim_strsave(buf);
|
||||
|
||||
return output->vval.v_string == NULL ? FAIL : OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of map() and filter() for a String. Apply "expr" to every
|
||||
* character in string "str" and return the result in "rettv".
|
||||
*/
|
||||
void
|
||||
string_filter_map(
|
||||
char_u *str,
|
||||
filtermap_T filtermap,
|
||||
typval_T *expr,
|
||||
typval_T *rettv)
|
||||
{
|
||||
char_u *p;
|
||||
typval_T tv;
|
||||
garray_T ga;
|
||||
int len = 0;
|
||||
int idx = 0;
|
||||
int rem;
|
||||
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
|
||||
// set_vim_var_nr() doesn't set the type
|
||||
set_vim_var_type(VV_KEY, VAR_NUMBER);
|
||||
|
||||
ga_init2(&ga, (int)sizeof(char), 80);
|
||||
for (p = str; *p != NUL; p += len)
|
||||
{
|
||||
typval_T newtv;
|
||||
|
||||
if (copy_first_char_to_tv(p, &tv) == FAIL)
|
||||
break;
|
||||
len = (int)STRLEN(tv.vval.v_string);
|
||||
|
||||
set_vim_var_nr(VV_KEY, idx);
|
||||
if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) == FAIL
|
||||
|| did_emsg)
|
||||
break;
|
||||
if (did_emsg)
|
||||
{
|
||||
clear_tv(&newtv);
|
||||
clear_tv(&tv);
|
||||
break;
|
||||
}
|
||||
else if (filtermap != FILTERMAP_FILTER)
|
||||
{
|
||||
if (newtv.v_type != VAR_STRING)
|
||||
{
|
||||
clear_tv(&newtv);
|
||||
clear_tv(&tv);
|
||||
emsg(_(e_stringreq));
|
||||
break;
|
||||
}
|
||||
else
|
||||
ga_concat(&ga, newtv.vval.v_string);
|
||||
}
|
||||
else if (!rem)
|
||||
ga_concat(&ga, tv.vval.v_string);
|
||||
|
||||
clear_tv(&newtv);
|
||||
clear_tv(&tv);
|
||||
|
||||
++idx;
|
||||
}
|
||||
ga_append(&ga, NUL);
|
||||
rettv->vval.v_string = ga.ga_data;
|
||||
}
|
||||
|
||||
/*
|
||||
* reduce() String argvars[0] using the function 'funcname' with arguments in
|
||||
* 'funcexe' starting with the initial value argvars[2] and return the result
|
||||
* in 'rettv'.
|
||||
*/
|
||||
void
|
||||
string_reduce(
|
||||
typval_T *argvars,
|
||||
char_u *func_name,
|
||||
funcexe_T *funcexe,
|
||||
typval_T *rettv)
|
||||
{
|
||||
char_u *p = tv_get_string(&argvars[0]);
|
||||
int len;
|
||||
typval_T argv[3];
|
||||
int r;
|
||||
int called_emsg_start = called_emsg;
|
||||
|
||||
if (argvars[2].v_type == VAR_UNKNOWN)
|
||||
{
|
||||
if (*p == NUL)
|
||||
{
|
||||
semsg(_(e_reduceempty), "String");
|
||||
return;
|
||||
}
|
||||
if (copy_first_char_to_tv(p, rettv) == FAIL)
|
||||
return;
|
||||
p += STRLEN(rettv->vval.v_string);
|
||||
}
|
||||
else if (argvars[2].v_type != VAR_STRING)
|
||||
{
|
||||
semsg(_(e_string_expected_for_argument_nr), 3);
|
||||
return;
|
||||
}
|
||||
else
|
||||
copy_tv(&argvars[2], rettv);
|
||||
|
||||
for ( ; *p != NUL; p += len)
|
||||
{
|
||||
argv[0] = *rettv;
|
||||
if (copy_first_char_to_tv(p, &argv[1]) == FAIL)
|
||||
break;
|
||||
len = (int)STRLEN(argv[1].vval.v_string);
|
||||
r = call_func(func_name, -1, rettv, 2, argv, funcexe);
|
||||
clear_tv(&argv[0]);
|
||||
clear_tv(&argv[1]);
|
||||
if (r == FAIL || called_emsg != called_emsg_start)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
byteidx(typval_T *argvars, typval_T *rettv, int comp UNUSED)
|
||||
{
|
||||
@@ -1686,9 +1864,6 @@ f_trim(typval_T *argvars, typval_T *rettv)
|
||||
rettv->vval.v_string = vim_strnsave(head, tail - head);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_EVAL)
|
||||
static char *e_printf = N_("E766: Insufficient arguments for printf()");
|
||||
|
||||
/*
|
||||
@@ -1766,6 +1941,7 @@ tv_float(typval_T *tvs, int *idxp)
|
||||
return f;
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_FLOAT
|
||||
|
Reference in New Issue
Block a user