Skip to content

Instantly share code, notes, and snippets.

@milesrout
Created December 10, 2016 02:39
Show Gist options
  • Save milesrout/c400ac151cafa38903596c0fcf261990 to your computer and use it in GitHub Desktop.
Save milesrout/c400ac151cafa38903596c0fcf261990 to your computer and use it in GitHub Desktop.
/*
* Evaluate the expression used in a ":for var in expr" command.
* "arg" points to "var".
* Set "*errp" to TRUE for an error, FALSE otherwise;
* Return a pointer that holds the info. Null when there is an error.
*/
void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip)
{
forinfo_T *fi;
char_u *expr;
typval_T tv;
list_T *l;
*errp = TRUE; /* default: there is an error */
fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T));
if (fi == NULL)
return NULL;
expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
if (expr == NULL)
return fi;
expr = skipwhite(expr);
if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) {
EMSG(_("E690: Missing \"in\" after :for"));
return fi;
}
if (skip)
++emsg_skip;
if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) {
*errp = FALSE;
if (!skip) {
l = tv.vval.v_list;
if (tv.v_type != VAR_LIST || l == NULL) {
EMSG(_(e_listreq));
clear_tv(&tv);
} else {
/* No need to increment the refcount, it's already set for the
* list being used in "tv". */
fi->fi_list = l;
list_add_watch(l, &fi->fi_lw);
fi->fi_lw.lw_item = l->lv_first;
}
}
}
if (skip)
--emsg_skip;
return fi;
}
if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) {
EMSG(_("E690: Missing \"in\" after :for"));
return fi;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment