Mercurial > vim
comparison src/eval.c @ 8538:c337c813c64d v7.4.1559
commit https://github.com/vim/vim/commit/1735bc988c546cc962c5f94792815b4d7cb79710
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Mar 14 23:05:14 2016 +0100
patch 7.4.1559
Problem: Passing cookie to a callback is clumsy.
Solution: Change function() to take arguments and return a partial.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 14 Mar 2016 23:15:05 +0100 |
parents | 09041d2fd7d0 |
children | 24db3583c496 |
comparison
equal
deleted
inserted
replaced
8537:cc20abebafa3 | 8538:c337c813c64d |
---|---|
450 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); | 450 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); |
451 static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); | 451 static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); |
452 static char_u *string_quote(char_u *str, int function); | 452 static char_u *string_quote(char_u *str, int function); |
453 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); | 453 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); |
454 static int find_internal_func(char_u *name); | 454 static int find_internal_func(char_u *name); |
455 static char_u *deref_func_name(char_u *name, int *lenp, int no_autoload); | 455 static char_u *deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload); |
456 static int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict); | 456 static int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict); |
457 static void emsg_funcname(char *ermsg, char_u *name); | 457 static void emsg_funcname(char *ermsg, char_u *name); |
458 static int non_zero_arg(typval_T *argvars); | 458 static int non_zero_arg(typval_T *argvars); |
459 | 459 |
460 #ifdef FEAT_FLOAT | 460 #ifdef FEAT_FLOAT |
461 static void f_abs(typval_T *argvars, typval_T *rettv); | 461 static void f_abs(typval_T *argvars, typval_T *rettv); |
1673 } | 1673 } |
1674 | 1674 |
1675 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ | 1675 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ |
1676 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, | 1676 ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, |
1677 curwin->w_cursor.lnum, curwin->w_cursor.lnum, | 1677 curwin->w_cursor.lnum, curwin->w_cursor.lnum, |
1678 &doesrange, TRUE, NULL); | 1678 &doesrange, TRUE, NULL, NULL); |
1679 if (safe) | 1679 if (safe) |
1680 { | 1680 { |
1681 --sandbox; | 1681 --sandbox; |
1682 restore_funccal(save_funccalp); | 1682 restore_funccal(save_funccalp); |
1683 } | 1683 } |
3089 switch (tv1->v_type) | 3089 switch (tv1->v_type) |
3090 { | 3090 { |
3091 case VAR_UNKNOWN: | 3091 case VAR_UNKNOWN: |
3092 case VAR_DICT: | 3092 case VAR_DICT: |
3093 case VAR_FUNC: | 3093 case VAR_FUNC: |
3094 case VAR_PARTIAL: | |
3094 case VAR_SPECIAL: | 3095 case VAR_SPECIAL: |
3095 case VAR_JOB: | 3096 case VAR_JOB: |
3096 case VAR_CHANNEL: | 3097 case VAR_CHANNEL: |
3097 break; | 3098 break; |
3098 | 3099 |
3454 typval_T rettv; | 3455 typval_T rettv; |
3455 linenr_T lnum; | 3456 linenr_T lnum; |
3456 int doesrange; | 3457 int doesrange; |
3457 int failed = FALSE; | 3458 int failed = FALSE; |
3458 funcdict_T fudi; | 3459 funcdict_T fudi; |
3460 partial_T *partial; | |
3459 | 3461 |
3460 if (eap->skip) | 3462 if (eap->skip) |
3461 { | 3463 { |
3462 /* trans_function_name() doesn't work well when skipping, use eval0() | 3464 /* trans_function_name() doesn't work well when skipping, use eval0() |
3463 * instead to skip to any following command, e.g. for: | 3465 * instead to skip to any following command, e.g. for: |
3484 if (fudi.fd_dict != NULL) | 3486 if (fudi.fd_dict != NULL) |
3485 ++fudi.fd_dict->dv_refcount; | 3487 ++fudi.fd_dict->dv_refcount; |
3486 | 3488 |
3487 /* If it is the name of a variable of type VAR_FUNC use its contents. */ | 3489 /* If it is the name of a variable of type VAR_FUNC use its contents. */ |
3488 len = (int)STRLEN(tofree); | 3490 len = (int)STRLEN(tofree); |
3489 name = deref_func_name(tofree, &len, FALSE); | 3491 name = deref_func_name(tofree, &len, &partial, FALSE); |
3490 | 3492 |
3491 /* Skip white space to allow ":call func ()". Not good, but required for | 3493 /* Skip white space to allow ":call func ()". Not good, but required for |
3492 * backward compatibility. */ | 3494 * backward compatibility. */ |
3493 startarg = skipwhite(arg); | 3495 startarg = skipwhite(arg); |
3494 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ | 3496 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ |
3523 #endif | 3525 #endif |
3524 } | 3526 } |
3525 arg = startarg; | 3527 arg = startarg; |
3526 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, | 3528 if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg, |
3527 eap->line1, eap->line2, &doesrange, | 3529 eap->line1, eap->line2, &doesrange, |
3528 !eap->skip, fudi.fd_dict) == FAIL) | 3530 !eap->skip, partial, fudi.fd_dict) == FAIL) |
3529 { | 3531 { |
3530 failed = TRUE; | 3532 failed = TRUE; |
3531 break; | 3533 break; |
3532 } | 3534 } |
3533 | 3535 |
3868 { | 3870 { |
3869 case VAR_UNKNOWN: | 3871 case VAR_UNKNOWN: |
3870 case VAR_NUMBER: | 3872 case VAR_NUMBER: |
3871 case VAR_STRING: | 3873 case VAR_STRING: |
3872 case VAR_FUNC: | 3874 case VAR_FUNC: |
3875 case VAR_PARTIAL: | |
3873 case VAR_FLOAT: | 3876 case VAR_FLOAT: |
3874 case VAR_SPECIAL: | 3877 case VAR_SPECIAL: |
3875 case VAR_JOB: | 3878 case VAR_JOB: |
3876 case VAR_CHANNEL: | 3879 case VAR_CHANNEL: |
3877 break; | 3880 break; |
4540 if (type == TYPE_NEQUAL) | 4543 if (type == TYPE_NEQUAL) |
4541 n1 = !n1; | 4544 n1 = !n1; |
4542 } | 4545 } |
4543 } | 4546 } |
4544 | 4547 |
4545 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) | 4548 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC |
4549 || rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL) | |
4546 { | 4550 { |
4547 if (rettv->v_type != var2.v_type | 4551 if (rettv->v_type != var2.v_type |
4548 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | 4552 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) |
4549 { | 4553 { |
4550 if (rettv->v_type != var2.v_type) | 4554 if (rettv->v_type != var2.v_type) |
4553 EMSG(_("E694: Invalid operation for Funcrefs")); | 4557 EMSG(_("E694: Invalid operation for Funcrefs")); |
4554 clear_tv(rettv); | 4558 clear_tv(rettv); |
4555 clear_tv(&var2); | 4559 clear_tv(&var2); |
4556 return FAIL; | 4560 return FAIL; |
4557 } | 4561 } |
4562 else if (rettv->v_type == VAR_PARTIAL) | |
4563 { | |
4564 /* Partials are only equal when identical. */ | |
4565 n1 = rettv->vval.v_partial != NULL | |
4566 && rettv->vval.v_partial == var2.vval.v_partial; | |
4567 } | |
4558 else | 4568 else |
4559 { | 4569 { |
4560 /* Compare two Funcrefs for being equal or unequal. */ | 4570 /* Compare two Funcrefs for being equal or unequal. */ |
4561 if (rettv->vval.v_string == NULL | 4571 if (rettv->vval.v_string == NULL |
4562 || var2.vval.v_string == NULL) | 4572 || var2.vval.v_string == NULL) |
4563 n1 = FALSE; | 4573 n1 = FALSE; |
4564 else | 4574 else |
4565 n1 = STRCMP(rettv->vval.v_string, | 4575 n1 = STRCMP(rettv->vval.v_string, |
4566 var2.vval.v_string) == 0; | 4576 var2.vval.v_string) == 0; |
4567 if (type == TYPE_NEQUAL) | |
4568 n1 = !n1; | |
4569 } | 4577 } |
4578 if (type == TYPE_NEQUAL) | |
4579 n1 = !n1; | |
4570 } | 4580 } |
4571 | 4581 |
4572 #ifdef FEAT_FLOAT | 4582 #ifdef FEAT_FLOAT |
4573 /* | 4583 /* |
4574 * If one of the two variables is a float, compare as a float. | 4584 * If one of the two variables is a float, compare as a float. |
5228 ret = FAIL; | 5238 ret = FAIL; |
5229 else | 5239 else |
5230 { | 5240 { |
5231 if (**arg == '(') /* recursive! */ | 5241 if (**arg == '(') /* recursive! */ |
5232 { | 5242 { |
5243 partial_T *partial; | |
5244 | |
5233 /* If "s" is the name of a variable of type VAR_FUNC | 5245 /* If "s" is the name of a variable of type VAR_FUNC |
5234 * use its contents. */ | 5246 * use its contents. */ |
5235 s = deref_func_name(s, &len, !evaluate); | 5247 s = deref_func_name(s, &len, &partial, !evaluate); |
5236 | 5248 |
5237 /* Invoke the function. */ | 5249 /* Invoke the function. */ |
5238 ret = get_func_tv(s, len, rettv, arg, | 5250 ret = get_func_tv(s, len, rettv, arg, |
5239 curwin->w_cursor.lnum, curwin->w_cursor.lnum, | 5251 curwin->w_cursor.lnum, curwin->w_cursor.lnum, |
5240 &len, evaluate, NULL); | 5252 &len, evaluate, partial, NULL); |
5241 | 5253 |
5242 /* If evaluate is FALSE rettv->v_type was not set in | 5254 /* If evaluate is FALSE rettv->v_type was not set in |
5243 * get_func_tv, but it's needed in handle_subscript() to parse | 5255 * get_func_tv, but it's needed in handle_subscript() to parse |
5244 * what follows. So set it here. */ | 5256 * what follows. So set it here. */ |
5245 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') | 5257 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') |
5357 char_u *key = NULL; | 5369 char_u *key = NULL; |
5358 | 5370 |
5359 switch (rettv->v_type) | 5371 switch (rettv->v_type) |
5360 { | 5372 { |
5361 case VAR_FUNC: | 5373 case VAR_FUNC: |
5374 case VAR_PARTIAL: | |
5362 if (verbose) | 5375 if (verbose) |
5363 EMSG(_("E695: Cannot index a Funcref")); | 5376 EMSG(_("E695: Cannot index a Funcref")); |
5364 return FAIL; | 5377 return FAIL; |
5365 case VAR_FLOAT: | 5378 case VAR_FLOAT: |
5366 #ifdef FEAT_FLOAT | 5379 #ifdef FEAT_FLOAT |
5478 | 5491 |
5479 switch (rettv->v_type) | 5492 switch (rettv->v_type) |
5480 { | 5493 { |
5481 case VAR_UNKNOWN: | 5494 case VAR_UNKNOWN: |
5482 case VAR_FUNC: | 5495 case VAR_FUNC: |
5496 case VAR_PARTIAL: | |
5483 case VAR_FLOAT: | 5497 case VAR_FLOAT: |
5484 case VAR_SPECIAL: | 5498 case VAR_SPECIAL: |
5485 case VAR_JOB: | 5499 case VAR_JOB: |
5486 case VAR_CHANNEL: | 5500 case VAR_CHANNEL: |
5487 break; /* not evaluating, skipping over subscript */ | 5501 break; /* not evaluating, skipping over subscript */ |
6216 case VAR_FUNC: | 6230 case VAR_FUNC: |
6217 return (tv1->vval.v_string != NULL | 6231 return (tv1->vval.v_string != NULL |
6218 && tv2->vval.v_string != NULL | 6232 && tv2->vval.v_string != NULL |
6219 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); | 6233 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); |
6220 | 6234 |
6235 case VAR_PARTIAL: | |
6236 return tv1->vval.v_partial != NULL | |
6237 && tv1->vval.v_partial == tv2->vval.v_partial; | |
6238 | |
6221 case VAR_NUMBER: | 6239 case VAR_NUMBER: |
6222 return tv1->vval.v_number == tv2->vval.v_number; | 6240 return tv1->vval.v_number == tv2->vval.v_number; |
6223 | 6241 |
6224 case VAR_STRING: | 6242 case VAR_STRING: |
6225 s1 = get_tv_string_buf(tv1, buf1); | 6243 s1 = get_tv_string_buf(tv1, buf1); |
7791 case VAR_FUNC: | 7809 case VAR_FUNC: |
7792 *tofree = NULL; | 7810 *tofree = NULL; |
7793 r = tv->vval.v_string; | 7811 r = tv->vval.v_string; |
7794 break; | 7812 break; |
7795 | 7813 |
7814 case VAR_PARTIAL: | |
7815 *tofree = NULL; | |
7816 /* TODO: arguments */ | |
7817 r = tv->vval.v_partial == NULL ? NULL : tv->vval.v_partial->pt_name; | |
7818 break; | |
7819 | |
7796 case VAR_LIST: | 7820 case VAR_LIST: |
7797 if (tv->vval.v_list == NULL) | 7821 if (tv->vval.v_list == NULL) |
7798 { | 7822 { |
7799 *tofree = NULL; | 7823 *tofree = NULL; |
7800 r = NULL; | 7824 r = NULL; |
7876 switch (tv->v_type) | 7900 switch (tv->v_type) |
7877 { | 7901 { |
7878 case VAR_FUNC: | 7902 case VAR_FUNC: |
7879 *tofree = string_quote(tv->vval.v_string, TRUE); | 7903 *tofree = string_quote(tv->vval.v_string, TRUE); |
7880 return *tofree; | 7904 return *tofree; |
7905 case VAR_PARTIAL: | |
7906 *tofree = string_quote(tv->vval.v_partial == NULL ? NULL | |
7907 : tv->vval.v_partial->pt_name, TRUE); | |
7908 return *tofree; | |
7881 case VAR_STRING: | 7909 case VAR_STRING: |
7882 *tofree = string_quote(tv->vval.v_string, FALSE); | 7910 *tofree = string_quote(tv->vval.v_string, FALSE); |
7883 return *tofree; | 7911 return *tofree; |
7884 case VAR_FLOAT: | 7912 case VAR_FLOAT: |
7885 #ifdef FEAT_FLOAT | 7913 #ifdef FEAT_FLOAT |
8144 {"foldclosedend", 1, 1, f_foldclosedend}, | 8172 {"foldclosedend", 1, 1, f_foldclosedend}, |
8145 {"foldlevel", 1, 1, f_foldlevel}, | 8173 {"foldlevel", 1, 1, f_foldlevel}, |
8146 {"foldtext", 0, 0, f_foldtext}, | 8174 {"foldtext", 0, 0, f_foldtext}, |
8147 {"foldtextresult", 1, 1, f_foldtextresult}, | 8175 {"foldtextresult", 1, 1, f_foldtextresult}, |
8148 {"foreground", 0, 0, f_foreground}, | 8176 {"foreground", 0, 0, f_foreground}, |
8149 {"function", 1, 1, f_function}, | 8177 {"function", 1, 3, f_function}, |
8150 {"garbagecollect", 0, 1, f_garbagecollect}, | 8178 {"garbagecollect", 0, 1, f_garbagecollect}, |
8151 {"get", 2, 3, f_get}, | 8179 {"get", 2, 3, f_get}, |
8152 {"getbufline", 2, 3, f_getbufline}, | 8180 {"getbufline", 2, 3, f_getbufline}, |
8153 {"getbufvar", 2, 3, f_getbufvar}, | 8181 {"getbufvar", 2, 3, f_getbufvar}, |
8154 {"getchar", 0, 1, f_getchar}, | 8182 {"getchar", 0, 1, f_getchar}, |
8522 } | 8550 } |
8523 | 8551 |
8524 /* | 8552 /* |
8525 * Check if "name" is a variable of type VAR_FUNC. If so, return the function | 8553 * Check if "name" is a variable of type VAR_FUNC. If so, return the function |
8526 * name it contains, otherwise return "name". | 8554 * name it contains, otherwise return "name". |
8555 * If "name" is of type VAR_PARTIAL also return "partial" | |
8527 */ | 8556 */ |
8528 static char_u * | 8557 static char_u * |
8529 deref_func_name(char_u *name, int *lenp, int no_autoload) | 8558 deref_func_name(char_u *name, int *lenp, partial_T **partial, int no_autoload) |
8530 { | 8559 { |
8531 dictitem_T *v; | 8560 dictitem_T *v; |
8532 int cc; | 8561 int cc; |
8562 | |
8563 *partial = NULL; | |
8533 | 8564 |
8534 cc = name[*lenp]; | 8565 cc = name[*lenp]; |
8535 name[*lenp] = NUL; | 8566 name[*lenp] = NUL; |
8536 v = find_var(name, NULL, no_autoload); | 8567 v = find_var(name, NULL, no_autoload); |
8537 name[*lenp] = cc; | 8568 name[*lenp] = cc; |
8542 *lenp = 0; | 8573 *lenp = 0; |
8543 return (char_u *)""; /* just in case */ | 8574 return (char_u *)""; /* just in case */ |
8544 } | 8575 } |
8545 *lenp = (int)STRLEN(v->di_tv.vval.v_string); | 8576 *lenp = (int)STRLEN(v->di_tv.vval.v_string); |
8546 return v->di_tv.vval.v_string; | 8577 return v->di_tv.vval.v_string; |
8578 } | |
8579 | |
8580 if (v != NULL && v->di_tv.v_type == VAR_PARTIAL) | |
8581 { | |
8582 *partial = v->di_tv.vval.v_partial; | |
8583 if (*partial == NULL) | |
8584 { | |
8585 *lenp = 0; | |
8586 return (char_u *)""; /* just in case */ | |
8587 } | |
8588 *lenp = (int)STRLEN((*partial)->pt_name); | |
8589 return (*partial)->pt_name; | |
8547 } | 8590 } |
8548 | 8591 |
8549 return name; | 8592 return name; |
8550 } | 8593 } |
8551 | 8594 |
8561 char_u **arg, /* argument, pointing to the '(' */ | 8604 char_u **arg, /* argument, pointing to the '(' */ |
8562 linenr_T firstline, /* first line of range */ | 8605 linenr_T firstline, /* first line of range */ |
8563 linenr_T lastline, /* last line of range */ | 8606 linenr_T lastline, /* last line of range */ |
8564 int *doesrange, /* return: function handled range */ | 8607 int *doesrange, /* return: function handled range */ |
8565 int evaluate, | 8608 int evaluate, |
8609 partial_T *partial, /* for extra arguments */ | |
8566 dict_T *selfdict) /* Dictionary for "self" */ | 8610 dict_T *selfdict) /* Dictionary for "self" */ |
8567 { | 8611 { |
8568 char_u *argp; | 8612 char_u *argp; |
8569 int ret = OK; | 8613 int ret = OK; |
8570 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ | 8614 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ |
8572 | 8616 |
8573 /* | 8617 /* |
8574 * Get the arguments. | 8618 * Get the arguments. |
8575 */ | 8619 */ |
8576 argp = *arg; | 8620 argp = *arg; |
8577 while (argcount < MAX_FUNC_ARGS) | 8621 while (argcount < MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) |
8578 { | 8622 { |
8579 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ | 8623 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ |
8580 if (*argp == ')' || *argp == ',' || *argp == NUL) | 8624 if (*argp == ')' || *argp == ',' || *argp == NUL) |
8581 break; | 8625 break; |
8582 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) | 8626 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) |
8593 else | 8637 else |
8594 ret = FAIL; | 8638 ret = FAIL; |
8595 | 8639 |
8596 if (ret == OK) | 8640 if (ret == OK) |
8597 ret = call_func(name, len, rettv, argcount, argvars, | 8641 ret = call_func(name, len, rettv, argcount, argvars, |
8598 firstline, lastline, doesrange, evaluate, selfdict); | 8642 firstline, lastline, doesrange, evaluate, partial, selfdict); |
8599 else if (!aborting()) | 8643 else if (!aborting()) |
8600 { | 8644 { |
8601 if (argcount == MAX_FUNC_ARGS) | 8645 if (argcount == MAX_FUNC_ARGS) |
8602 emsg_funcname(N_("E740: Too many arguments for function %s"), name); | 8646 emsg_funcname(N_("E740: Too many arguments for function %s"), name); |
8603 else | 8647 else |
8620 int | 8664 int |
8621 call_func( | 8665 call_func( |
8622 char_u *funcname, /* name of the function */ | 8666 char_u *funcname, /* name of the function */ |
8623 int len, /* length of "name" */ | 8667 int len, /* length of "name" */ |
8624 typval_T *rettv, /* return value goes here */ | 8668 typval_T *rettv, /* return value goes here */ |
8625 int argcount, /* number of "argvars" */ | 8669 int argcount_in, /* number of "argvars" */ |
8626 typval_T *argvars, /* vars for arguments, must have "argcount" | 8670 typval_T *argvars_in, /* vars for arguments, must have "argcount" |
8627 PLUS ONE elements! */ | 8671 PLUS ONE elements! */ |
8628 linenr_T firstline, /* first line of range */ | 8672 linenr_T firstline, /* first line of range */ |
8629 linenr_T lastline, /* last line of range */ | 8673 linenr_T lastline, /* last line of range */ |
8630 int *doesrange, /* return: function handled range */ | 8674 int *doesrange, /* return: function handled range */ |
8631 int evaluate, | 8675 int evaluate, |
8632 dict_T *selfdict) /* Dictionary for "self" */ | 8676 partial_T *partial, /* optional, can be NULL */ |
8677 dict_T *selfdict_in) /* Dictionary for "self" */ | |
8633 { | 8678 { |
8634 int ret = FAIL; | 8679 int ret = FAIL; |
8635 #define ERROR_UNKNOWN 0 | 8680 #define ERROR_UNKNOWN 0 |
8636 #define ERROR_TOOMANY 1 | 8681 #define ERROR_TOOMANY 1 |
8637 #define ERROR_TOOFEW 2 | 8682 #define ERROR_TOOFEW 2 |
8638 #define ERROR_SCRIPT 3 | 8683 #define ERROR_SCRIPT 3 |
8639 #define ERROR_DICT 4 | 8684 #define ERROR_DICT 4 |
8640 #define ERROR_NONE 5 | 8685 #define ERROR_NONE 5 |
8641 #define ERROR_OTHER 6 | 8686 #define ERROR_OTHER 6 |
8687 #define ERROR_BOTH 7 | |
8642 int error = ERROR_NONE; | 8688 int error = ERROR_NONE; |
8643 int i; | 8689 int i; |
8644 int llen; | 8690 int llen; |
8645 ufunc_T *fp; | 8691 ufunc_T *fp; |
8646 #define FLEN_FIXED 40 | 8692 #define FLEN_FIXED 40 |
8647 char_u fname_buf[FLEN_FIXED + 1]; | 8693 char_u fname_buf[FLEN_FIXED + 1]; |
8648 char_u *fname; | 8694 char_u *fname; |
8649 char_u *name; | 8695 char_u *name; |
8696 int argcount = argcount_in; | |
8697 typval_T *argvars = argvars_in; | |
8698 dict_T *selfdict = selfdict_in; | |
8699 typval_T argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */ | |
8700 int argv_clear = 0; | |
8650 | 8701 |
8651 /* Make a copy of the name, if it comes from a funcref variable it could | 8702 /* Make a copy of the name, if it comes from a funcref variable it could |
8652 * be changed or deleted in the called function. */ | 8703 * be changed or deleted in the called function. */ |
8653 name = vim_strnsave(funcname, len); | 8704 name = vim_strnsave(funcname, len); |
8654 if (name == NULL) | 8705 if (name == NULL) |
8695 } | 8746 } |
8696 else | 8747 else |
8697 fname = name; | 8748 fname = name; |
8698 | 8749 |
8699 *doesrange = FALSE; | 8750 *doesrange = FALSE; |
8751 | |
8752 if (partial != NULL) | |
8753 { | |
8754 if (partial->pt_dict != NULL) | |
8755 { | |
8756 if (selfdict_in != NULL) | |
8757 error = ERROR_BOTH; | |
8758 selfdict = partial->pt_dict; | |
8759 } | |
8760 if (error == ERROR_NONE && partial->pt_argc > 0) | |
8761 { | |
8762 int i; | |
8763 | |
8764 for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear) | |
8765 copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]); | |
8766 for (i = 0; i < argcount_in; ++i) | |
8767 argv[i + argv_clear] = argvars_in[i]; | |
8768 argvars = argv; | |
8769 argcount = partial->pt_argc + argcount_in; | |
8770 } | |
8771 } | |
8700 | 8772 |
8701 | 8773 |
8702 /* execute the function if no errors detected and executing */ | 8774 /* execute the function if no errors detected and executing */ |
8703 if (evaluate && error == ERROR_NONE) | 8775 if (evaluate && error == ERROR_NONE) |
8704 { | 8776 { |
8839 break; | 8911 break; |
8840 case ERROR_DICT: | 8912 case ERROR_DICT: |
8841 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), | 8913 emsg_funcname(N_("E725: Calling dict function without Dictionary: %s"), |
8842 name); | 8914 name); |
8843 break; | 8915 break; |
8844 } | 8916 case ERROR_BOTH: |
8845 } | 8917 emsg_funcname(N_("E924: can't have both a \"self\" dict and a partial: %s"), |
8846 | 8918 name); |
8919 break; | |
8920 } | |
8921 } | |
8922 | |
8923 while (argv_clear > 0) | |
8924 clear_tv(&argv[--argv_clear]); | |
8847 if (fname != name && fname != fname_buf) | 8925 if (fname != name && fname != fname_buf) |
8848 vim_free(fname); | 8926 vim_free(fname); |
8849 vim_free(name); | 8927 vim_free(name); |
8850 | 8928 |
8851 return ret; | 8929 return ret; |
9735 | 9813 |
9736 int | 9814 int |
9737 func_call( | 9815 func_call( |
9738 char_u *name, | 9816 char_u *name, |
9739 typval_T *args, | 9817 typval_T *args, |
9818 partial_T *partial, | |
9740 dict_T *selfdict, | 9819 dict_T *selfdict, |
9741 typval_T *rettv) | 9820 typval_T *rettv) |
9742 { | 9821 { |
9743 listitem_T *item; | 9822 listitem_T *item; |
9744 typval_T argv[MAX_FUNC_ARGS + 1]; | 9823 typval_T argv[MAX_FUNC_ARGS + 1]; |
9747 int r = 0; | 9826 int r = 0; |
9748 | 9827 |
9749 for (item = args->vval.v_list->lv_first; item != NULL; | 9828 for (item = args->vval.v_list->lv_first; item != NULL; |
9750 item = item->li_next) | 9829 item = item->li_next) |
9751 { | 9830 { |
9752 if (argc == MAX_FUNC_ARGS) | 9831 if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) |
9753 { | 9832 { |
9754 EMSG(_("E699: Too many arguments")); | 9833 EMSG(_("E699: Too many arguments")); |
9755 break; | 9834 break; |
9756 } | 9835 } |
9757 /* Make a copy of each argument. This is needed to be able to set | 9836 /* Make a copy of each argument. This is needed to be able to set |
9761 } | 9840 } |
9762 | 9841 |
9763 if (item == NULL) | 9842 if (item == NULL) |
9764 r = call_func(name, (int)STRLEN(name), rettv, argc, argv, | 9843 r = call_func(name, (int)STRLEN(name), rettv, argc, argv, |
9765 curwin->w_cursor.lnum, curwin->w_cursor.lnum, | 9844 curwin->w_cursor.lnum, curwin->w_cursor.lnum, |
9766 &dummy, TRUE, selfdict); | 9845 &dummy, TRUE, partial, selfdict); |
9767 | 9846 |
9768 /* Free the arguments. */ | 9847 /* Free the arguments. */ |
9769 while (argc > 0) | 9848 while (argc > 0) |
9770 clear_tv(&argv[--argc]); | 9849 clear_tv(&argv[--argc]); |
9771 | 9850 |
9772 return r; | 9851 return r; |
9773 } | 9852 } |
9774 | 9853 |
9775 /* | 9854 /* |
9776 * "call(func, arglist)" function | 9855 * "call(func, arglist [, dict])" function |
9777 */ | 9856 */ |
9778 static void | 9857 static void |
9779 f_call(typval_T *argvars, typval_T *rettv) | 9858 f_call(typval_T *argvars, typval_T *rettv) |
9780 { | 9859 { |
9781 char_u *func; | 9860 char_u *func; |
9861 partial_T *partial = NULL; | |
9782 dict_T *selfdict = NULL; | 9862 dict_T *selfdict = NULL; |
9783 | 9863 |
9784 if (argvars[1].v_type != VAR_LIST) | 9864 if (argvars[1].v_type != VAR_LIST) |
9785 { | 9865 { |
9786 EMSG(_(e_listreq)); | 9866 EMSG(_(e_listreq)); |
9789 if (argvars[1].vval.v_list == NULL) | 9869 if (argvars[1].vval.v_list == NULL) |
9790 return; | 9870 return; |
9791 | 9871 |
9792 if (argvars[0].v_type == VAR_FUNC) | 9872 if (argvars[0].v_type == VAR_FUNC) |
9793 func = argvars[0].vval.v_string; | 9873 func = argvars[0].vval.v_string; |
9874 else if (argvars[0].v_type == VAR_PARTIAL) | |
9875 { | |
9876 partial = argvars[0].vval.v_partial; | |
9877 func = partial->pt_name; | |
9878 } | |
9794 else | 9879 else |
9795 func = get_tv_string(&argvars[0]); | 9880 func = get_tv_string(&argvars[0]); |
9796 if (*func == NUL) | 9881 if (*func == NUL) |
9797 return; /* type error or empty name */ | 9882 return; /* type error or empty name */ |
9798 | 9883 |
9804 return; | 9889 return; |
9805 } | 9890 } |
9806 selfdict = argvars[2].vval.v_dict; | 9891 selfdict = argvars[2].vval.v_dict; |
9807 } | 9892 } |
9808 | 9893 |
9809 (void)func_call(func, &argvars[1], selfdict, rettv); | 9894 (void)func_call(func, &argvars[1], partial, selfdict, rettv); |
9810 } | 9895 } |
9811 | 9896 |
9812 #ifdef FEAT_FLOAT | 9897 #ifdef FEAT_FLOAT |
9813 /* | 9898 /* |
9814 * "ceil({float})" function | 9899 * "ceil({float})" function |
10624 { | 10709 { |
10625 case VAR_STRING: | 10710 case VAR_STRING: |
10626 case VAR_FUNC: | 10711 case VAR_FUNC: |
10627 n = argvars[0].vval.v_string == NULL | 10712 n = argvars[0].vval.v_string == NULL |
10628 || *argvars[0].vval.v_string == NUL; | 10713 || *argvars[0].vval.v_string == NUL; |
10714 break; | |
10715 case VAR_PARTIAL: | |
10716 n = FALSE; | |
10629 break; | 10717 break; |
10630 case VAR_NUMBER: | 10718 case VAR_NUMBER: |
10631 n = argvars[0].vval.v_number == 0; | 10719 n = argvars[0].vval.v_number == 0; |
10632 break; | 10720 break; |
10633 case VAR_FLOAT: | 10721 case VAR_FLOAT: |
11686 */ | 11774 */ |
11687 static void | 11775 static void |
11688 f_function(typval_T *argvars, typval_T *rettv) | 11776 f_function(typval_T *argvars, typval_T *rettv) |
11689 { | 11777 { |
11690 char_u *s; | 11778 char_u *s; |
11779 char_u *name; | |
11691 | 11780 |
11692 s = get_tv_string(&argvars[0]); | 11781 s = get_tv_string(&argvars[0]); |
11693 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) | 11782 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) |
11694 EMSG2(_(e_invarg2), s); | 11783 EMSG2(_(e_invarg2), s); |
11695 /* Don't check an autoload name for existence here. */ | 11784 /* Don't check an autoload name for existence here. */ |
11705 /* Expand s: and <SID> into <SNR>nr_, so that the function can | 11794 /* Expand s: and <SID> into <SNR>nr_, so that the function can |
11706 * also be called from another script. Using trans_function_name() | 11795 * also be called from another script. Using trans_function_name() |
11707 * would also work, but some plugins depend on the name being | 11796 * would also work, but some plugins depend on the name being |
11708 * printable text. */ | 11797 * printable text. */ |
11709 sprintf(sid_buf, "<SNR>%ld_", (long)current_SID); | 11798 sprintf(sid_buf, "<SNR>%ld_", (long)current_SID); |
11710 rettv->vval.v_string = | 11799 name = alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1)); |
11711 alloc((int)(STRLEN(sid_buf) + STRLEN(s + off) + 1)); | 11800 if (name != NULL) |
11712 if (rettv->vval.v_string != NULL) | |
11713 { | 11801 { |
11714 STRCPY(rettv->vval.v_string, sid_buf); | 11802 STRCPY(name, sid_buf); |
11715 STRCAT(rettv->vval.v_string, s + off); | 11803 STRCAT(name, s + off); |
11716 } | 11804 } |
11717 } | 11805 } |
11718 else | 11806 else |
11719 rettv->vval.v_string = vim_strsave(s); | 11807 name = vim_strsave(s); |
11720 rettv->v_type = VAR_FUNC; | 11808 |
11721 } | 11809 if (argvars[1].v_type != VAR_UNKNOWN) |
11810 { | |
11811 partial_T *pt; | |
11812 int dict_idx = 0; | |
11813 int arg_idx = 0; | |
11814 | |
11815 if (argvars[2].v_type != VAR_UNKNOWN) | |
11816 { | |
11817 /* function(name, [args], dict) */ | |
11818 arg_idx = 1; | |
11819 dict_idx = 2; | |
11820 } | |
11821 else if (argvars[1].v_type == VAR_DICT) | |
11822 /* function(name, dict) */ | |
11823 dict_idx = 1; | |
11824 else | |
11825 /* function(name, [args]) */ | |
11826 arg_idx = 1; | |
11827 if (dict_idx > 0 && (argvars[dict_idx].v_type != VAR_DICT | |
11828 || argvars[dict_idx].vval.v_dict == NULL)) | |
11829 { | |
11830 EMSG(_("E922: expected a dict")); | |
11831 vim_free(name); | |
11832 return; | |
11833 } | |
11834 if (arg_idx > 0 && (argvars[arg_idx].v_type != VAR_LIST | |
11835 || argvars[arg_idx].vval.v_list == NULL)) | |
11836 { | |
11837 EMSG(_("E923: Second argument of function() must be a list or a dict")); | |
11838 vim_free(name); | |
11839 return; | |
11840 } | |
11841 | |
11842 pt = (partial_T *)alloc_clear(sizeof(partial_T)); | |
11843 if (pt != NULL) | |
11844 { | |
11845 if (arg_idx > 0) | |
11846 { | |
11847 list_T *list = argvars[arg_idx].vval.v_list; | |
11848 listitem_T *li; | |
11849 int i = 0; | |
11850 | |
11851 pt->pt_argv = (typval_T *)alloc( | |
11852 sizeof(typval_T) * list->lv_len); | |
11853 if (pt->pt_argv == NULL) | |
11854 { | |
11855 vim_free(pt); | |
11856 vim_free(name); | |
11857 return; | |
11858 } | |
11859 else | |
11860 { | |
11861 pt->pt_argc = list->lv_len; | |
11862 for (li = list->lv_first; li != NULL; li = li->li_next) | |
11863 copy_tv(&li->li_tv, &pt->pt_argv[i++]); | |
11864 } | |
11865 } | |
11866 | |
11867 if (dict_idx > 0) | |
11868 { | |
11869 pt->pt_dict = argvars[dict_idx].vval.v_dict; | |
11870 ++pt->pt_dict->dv_refcount; | |
11871 } | |
11872 | |
11873 pt->pt_refcount = 1; | |
11874 pt->pt_name = name; | |
11875 func_ref(pt->pt_name); | |
11876 } | |
11877 rettv->v_type = VAR_PARTIAL; | |
11878 rettv->vval.v_partial = pt; | |
11879 } | |
11880 else | |
11881 { | |
11882 rettv->v_type = VAR_FUNC; | |
11883 rettv->vval.v_string = name; | |
11884 func_ref(name); | |
11885 } | |
11886 } | |
11887 } | |
11888 | |
11889 static void | |
11890 partial_free(partial_T *pt) | |
11891 { | |
11892 int i; | |
11893 | |
11894 for (i = 0; i < pt->pt_argc; ++i) | |
11895 clear_tv(&pt->pt_argv[i]); | |
11896 vim_free(pt->pt_argv); | |
11897 func_unref(pt->pt_name); | |
11898 vim_free(pt->pt_name); | |
11899 vim_free(pt); | |
11900 } | |
11901 | |
11902 /* | |
11903 * Unreference a closure: decrement the reference count and free it when it | |
11904 * becomes zero. | |
11905 */ | |
11906 void | |
11907 partial_unref(partial_T *pt) | |
11908 { | |
11909 if (pt != NULL && --pt->pt_refcount <= 0) | |
11910 partial_free(pt); | |
11722 } | 11911 } |
11723 | 11912 |
11724 /* | 11913 /* |
11725 * "garbagecollect()" function | 11914 * "garbagecollect()" function |
11726 */ | 11915 */ |
14596 break; | 14785 break; |
14597 case VAR_UNKNOWN: | 14786 case VAR_UNKNOWN: |
14598 case VAR_SPECIAL: | 14787 case VAR_SPECIAL: |
14599 case VAR_FLOAT: | 14788 case VAR_FLOAT: |
14600 case VAR_FUNC: | 14789 case VAR_FUNC: |
14790 case VAR_PARTIAL: | |
14601 case VAR_JOB: | 14791 case VAR_JOB: |
14602 case VAR_CHANNEL: | 14792 case VAR_CHANNEL: |
14603 EMSG(_("E701: Invalid type for len()")); | 14793 EMSG(_("E701: Invalid type for len()")); |
14604 break; | 14794 break; |
14605 } | 14795 } |
18167 int item_compare_numbers; | 18357 int item_compare_numbers; |
18168 #ifdef FEAT_FLOAT | 18358 #ifdef FEAT_FLOAT |
18169 int item_compare_float; | 18359 int item_compare_float; |
18170 #endif | 18360 #endif |
18171 char_u *item_compare_func; | 18361 char_u *item_compare_func; |
18362 partial_T *item_compare_partial; | |
18172 dict_T *item_compare_selfdict; | 18363 dict_T *item_compare_selfdict; |
18173 int item_compare_func_err; | 18364 int item_compare_func_err; |
18174 int item_compare_keep_zero; | 18365 int item_compare_keep_zero; |
18175 } sortinfo_T; | 18366 } sortinfo_T; |
18176 static sortinfo_T *sortinfo = NULL; | 18367 static sortinfo_T *sortinfo = NULL; |
18276 sortItem_T *si1, *si2; | 18467 sortItem_T *si1, *si2; |
18277 int res; | 18468 int res; |
18278 typval_T rettv; | 18469 typval_T rettv; |
18279 typval_T argv[3]; | 18470 typval_T argv[3]; |
18280 int dummy; | 18471 int dummy; |
18472 char_u *func_name; | |
18473 partial_T *partial = sortinfo->item_compare_partial; | |
18281 | 18474 |
18282 /* shortcut after failure in previous call; compare all items equal */ | 18475 /* shortcut after failure in previous call; compare all items equal */ |
18283 if (sortinfo->item_compare_func_err) | 18476 if (sortinfo->item_compare_func_err) |
18284 return 0; | 18477 return 0; |
18285 | 18478 |
18286 si1 = (sortItem_T *)s1; | 18479 si1 = (sortItem_T *)s1; |
18287 si2 = (sortItem_T *)s2; | 18480 si2 = (sortItem_T *)s2; |
18481 | |
18482 if (partial == NULL) | |
18483 func_name = sortinfo->item_compare_func; | |
18484 else | |
18485 func_name = partial->pt_name; | |
18288 | 18486 |
18289 /* Copy the values. This is needed to be able to set v_lock to VAR_FIXED | 18487 /* Copy the values. This is needed to be able to set v_lock to VAR_FIXED |
18290 * in the copy without changing the original list items. */ | 18488 * in the copy without changing the original list items. */ |
18291 copy_tv(&si1->item->li_tv, &argv[0]); | 18489 copy_tv(&si1->item->li_tv, &argv[0]); |
18292 copy_tv(&si2->item->li_tv, &argv[1]); | 18490 copy_tv(&si2->item->li_tv, &argv[1]); |
18293 | 18491 |
18294 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ | 18492 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ |
18295 res = call_func(sortinfo->item_compare_func, | 18493 res = call_func(func_name, (int)STRLEN(func_name), |
18296 (int)STRLEN(sortinfo->item_compare_func), | |
18297 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, | 18494 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, |
18298 sortinfo->item_compare_selfdict); | 18495 partial, sortinfo->item_compare_selfdict); |
18299 clear_tv(&argv[0]); | 18496 clear_tv(&argv[0]); |
18300 clear_tv(&argv[1]); | 18497 clear_tv(&argv[1]); |
18301 | 18498 |
18302 if (res == FAIL) | 18499 if (res == FAIL) |
18303 res = ITEM_COMPARE_FAIL; | 18500 res = ITEM_COMPARE_FAIL; |
18356 info.item_compare_numbers = FALSE; | 18553 info.item_compare_numbers = FALSE; |
18357 #ifdef FEAT_FLOAT | 18554 #ifdef FEAT_FLOAT |
18358 info.item_compare_float = FALSE; | 18555 info.item_compare_float = FALSE; |
18359 #endif | 18556 #endif |
18360 info.item_compare_func = NULL; | 18557 info.item_compare_func = NULL; |
18558 info.item_compare_partial = NULL; | |
18361 info.item_compare_selfdict = NULL; | 18559 info.item_compare_selfdict = NULL; |
18362 if (argvars[1].v_type != VAR_UNKNOWN) | 18560 if (argvars[1].v_type != VAR_UNKNOWN) |
18363 { | 18561 { |
18364 /* optional second argument: {func} */ | 18562 /* optional second argument: {func} */ |
18365 if (argvars[1].v_type == VAR_FUNC) | 18563 if (argvars[1].v_type == VAR_FUNC) |
18366 info.item_compare_func = argvars[1].vval.v_string; | 18564 info.item_compare_func = argvars[1].vval.v_string; |
18565 else if (argvars[1].v_type == VAR_PARTIAL) | |
18566 info.item_compare_partial = argvars[1].vval.v_partial; | |
18367 else | 18567 else |
18368 { | 18568 { |
18369 int error = FALSE; | 18569 int error = FALSE; |
18370 | 18570 |
18371 i = get_tv_number_chk(&argvars[1], &error); | 18571 i = get_tv_number_chk(&argvars[1], &error); |
18441 } | 18641 } |
18442 | 18642 |
18443 info.item_compare_func_err = FALSE; | 18643 info.item_compare_func_err = FALSE; |
18444 info.item_compare_keep_zero = FALSE; | 18644 info.item_compare_keep_zero = FALSE; |
18445 /* test the compare function */ | 18645 /* test the compare function */ |
18446 if (info.item_compare_func != NULL | 18646 if ((info.item_compare_func != NULL |
18647 || info.item_compare_partial != NULL) | |
18447 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) | 18648 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) |
18448 == ITEM_COMPARE_FAIL) | 18649 == ITEM_COMPARE_FAIL) |
18449 EMSG(_("E702: Sort compare function failed")); | 18650 EMSG(_("E702: Sort compare function failed")); |
18450 else | 18651 else |
18451 { | 18652 { |
18452 /* Sort the array with item pointers. */ | 18653 /* Sort the array with item pointers. */ |
18453 qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T), | 18654 qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T), |
18454 info.item_compare_func == NULL | 18655 info.item_compare_func == NULL |
18656 && info.item_compare_partial == NULL | |
18455 ? item_compare : item_compare2); | 18657 ? item_compare : item_compare2); |
18456 | 18658 |
18457 if (!info.item_compare_func_err) | 18659 if (!info.item_compare_func_err) |
18458 { | 18660 { |
18459 /* Clear the List and append the items in sorted order. */ | 18661 /* Clear the List and append the items in sorted order. */ |
18469 int (*item_compare_func_ptr)(const void *, const void *); | 18671 int (*item_compare_func_ptr)(const void *, const void *); |
18470 | 18672 |
18471 /* f_uniq(): ptrs will be a stack of items to remove */ | 18673 /* f_uniq(): ptrs will be a stack of items to remove */ |
18472 info.item_compare_func_err = FALSE; | 18674 info.item_compare_func_err = FALSE; |
18473 info.item_compare_keep_zero = TRUE; | 18675 info.item_compare_keep_zero = TRUE; |
18474 item_compare_func_ptr = info.item_compare_func | 18676 item_compare_func_ptr = info.item_compare_func != NULL |
18677 || info.item_compare_partial != NULL | |
18475 ? item_compare2 : item_compare; | 18678 ? item_compare2 : item_compare; |
18476 | 18679 |
18477 for (li = l->lv_first; li != NULL && li->li_next != NULL; | 18680 for (li = l->lv_first; li != NULL && li->li_next != NULL; |
18478 li = li->li_next) | 18681 li = li->li_next) |
18479 { | 18682 { |
20043 else | 20246 else |
20044 n = 7; | 20247 n = 7; |
20045 break; | 20248 break; |
20046 case VAR_JOB: n = 8; break; | 20249 case VAR_JOB: n = 8; break; |
20047 case VAR_CHANNEL: n = 9; break; | 20250 case VAR_CHANNEL: n = 9; break; |
20251 case VAR_PARTIAL: n = 10; break; | |
20048 case VAR_UNKNOWN: | 20252 case VAR_UNKNOWN: |
20049 EMSG2(_(e_intern2), "f_type(UNKNOWN)"); | 20253 EMSG2(_(e_intern2), "f_type(UNKNOWN)"); |
20050 n = -1; | 20254 n = -1; |
20051 break; | 20255 break; |
20052 } | 20256 } |
21293 int ret = OK; | 21497 int ret = OK; |
21294 dict_T *selfdict = NULL; | 21498 dict_T *selfdict = NULL; |
21295 char_u *s; | 21499 char_u *s; |
21296 int len; | 21500 int len; |
21297 typval_T functv; | 21501 typval_T functv; |
21502 partial_T *pt = NULL; | |
21298 | 21503 |
21299 while (ret == OK | 21504 while (ret == OK |
21300 && (**arg == '[' | 21505 && (**arg == '[' |
21301 || (**arg == '.' && rettv->v_type == VAR_DICT) | 21506 || (**arg == '.' && rettv->v_type == VAR_DICT) |
21302 || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC))) | 21507 || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC |
21508 || rettv->v_type == VAR_PARTIAL))) | |
21303 && !vim_iswhite(*(*arg - 1))) | 21509 && !vim_iswhite(*(*arg - 1))) |
21304 { | 21510 { |
21305 if (**arg == '(') | 21511 if (**arg == '(') |
21306 { | 21512 { |
21307 /* need to copy the funcref so that we can clear rettv */ | 21513 /* need to copy the funcref so that we can clear rettv */ |
21309 { | 21515 { |
21310 functv = *rettv; | 21516 functv = *rettv; |
21311 rettv->v_type = VAR_UNKNOWN; | 21517 rettv->v_type = VAR_UNKNOWN; |
21312 | 21518 |
21313 /* Invoke the function. Recursive! */ | 21519 /* Invoke the function. Recursive! */ |
21314 s = functv.vval.v_string; | 21520 if (rettv->v_type == VAR_PARTIAL) |
21521 { | |
21522 pt = functv.vval.v_partial; | |
21523 s = pt->pt_name; | |
21524 } | |
21525 else | |
21526 s = functv.vval.v_string; | |
21315 } | 21527 } |
21316 else | 21528 else |
21317 s = (char_u *)""; | 21529 s = (char_u *)""; |
21318 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, | 21530 ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, |
21319 curwin->w_cursor.lnum, curwin->w_cursor.lnum, | 21531 curwin->w_cursor.lnum, curwin->w_cursor.lnum, |
21320 &len, evaluate, selfdict); | 21532 &len, evaluate, pt, selfdict); |
21321 | 21533 |
21322 /* Clear the funcref afterwards, so that deleting it while | 21534 /* Clear the funcref afterwards, so that deleting it while |
21323 * evaluating the arguments is possible (see test55). */ | 21535 * evaluating the arguments is possible (see test55). */ |
21324 if (evaluate) | 21536 if (evaluate) |
21325 clear_tv(&functv); | 21537 clear_tv(&functv); |
21403 func_unref(varp->vval.v_string); | 21615 func_unref(varp->vval.v_string); |
21404 /*FALLTHROUGH*/ | 21616 /*FALLTHROUGH*/ |
21405 case VAR_STRING: | 21617 case VAR_STRING: |
21406 vim_free(varp->vval.v_string); | 21618 vim_free(varp->vval.v_string); |
21407 break; | 21619 break; |
21620 case VAR_PARTIAL: | |
21621 partial_unref(varp->vval.v_partial); | |
21622 break; | |
21408 case VAR_LIST: | 21623 case VAR_LIST: |
21409 list_unref(varp->vval.v_list); | 21624 list_unref(varp->vval.v_list); |
21410 break; | 21625 break; |
21411 case VAR_DICT: | 21626 case VAR_DICT: |
21412 dict_unref(varp->vval.v_dict); | 21627 dict_unref(varp->vval.v_dict); |
21445 func_unref(varp->vval.v_string); | 21660 func_unref(varp->vval.v_string); |
21446 /*FALLTHROUGH*/ | 21661 /*FALLTHROUGH*/ |
21447 case VAR_STRING: | 21662 case VAR_STRING: |
21448 vim_free(varp->vval.v_string); | 21663 vim_free(varp->vval.v_string); |
21449 varp->vval.v_string = NULL; | 21664 varp->vval.v_string = NULL; |
21665 break; | |
21666 case VAR_PARTIAL: | |
21667 partial_unref(varp->vval.v_partial); | |
21668 varp->vval.v_partial = NULL; | |
21450 break; | 21669 break; |
21451 case VAR_LIST: | 21670 case VAR_LIST: |
21452 list_unref(varp->vval.v_list); | 21671 list_unref(varp->vval.v_list); |
21453 varp->vval.v_list = NULL; | 21672 varp->vval.v_list = NULL; |
21454 break; | 21673 break; |
21522 #ifdef FEAT_FLOAT | 21741 #ifdef FEAT_FLOAT |
21523 EMSG(_("E805: Using a Float as a Number")); | 21742 EMSG(_("E805: Using a Float as a Number")); |
21524 break; | 21743 break; |
21525 #endif | 21744 #endif |
21526 case VAR_FUNC: | 21745 case VAR_FUNC: |
21746 case VAR_PARTIAL: | |
21527 EMSG(_("E703: Using a Funcref as a Number")); | 21747 EMSG(_("E703: Using a Funcref as a Number")); |
21528 break; | 21748 break; |
21529 case VAR_STRING: | 21749 case VAR_STRING: |
21530 if (varp->vval.v_string != NULL) | 21750 if (varp->vval.v_string != NULL) |
21531 vim_str2nr(varp->vval.v_string, NULL, NULL, | 21751 vim_str2nr(varp->vval.v_string, NULL, NULL, |
21570 case VAR_NUMBER: | 21790 case VAR_NUMBER: |
21571 return (float_T)(varp->vval.v_number); | 21791 return (float_T)(varp->vval.v_number); |
21572 case VAR_FLOAT: | 21792 case VAR_FLOAT: |
21573 return varp->vval.v_float; | 21793 return varp->vval.v_float; |
21574 case VAR_FUNC: | 21794 case VAR_FUNC: |
21795 case VAR_PARTIAL: | |
21575 EMSG(_("E891: Using a Funcref as a Float")); | 21796 EMSG(_("E891: Using a Funcref as a Float")); |
21576 break; | 21797 break; |
21577 case VAR_STRING: | 21798 case VAR_STRING: |
21578 EMSG(_("E892: Using a String as a Float")); | 21799 EMSG(_("E892: Using a String as a Float")); |
21579 break; | 21800 break; |
21686 { | 21907 { |
21687 case VAR_NUMBER: | 21908 case VAR_NUMBER: |
21688 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); | 21909 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); |
21689 return buf; | 21910 return buf; |
21690 case VAR_FUNC: | 21911 case VAR_FUNC: |
21912 case VAR_PARTIAL: | |
21691 EMSG(_("E729: using Funcref as a String")); | 21913 EMSG(_("E729: using Funcref as a String")); |
21692 break; | 21914 break; |
21693 case VAR_LIST: | 21915 case VAR_LIST: |
21694 EMSG(_("E730: using List as a String")); | 21916 EMSG(_("E730: using List as a String")); |
21695 break; | 21917 break; |
22085 msg_puts(name); | 22307 msg_puts(name); |
22086 msg_putchar(' '); | 22308 msg_putchar(' '); |
22087 msg_advance(22); | 22309 msg_advance(22); |
22088 if (type == VAR_NUMBER) | 22310 if (type == VAR_NUMBER) |
22089 msg_putchar('#'); | 22311 msg_putchar('#'); |
22090 else if (type == VAR_FUNC) | 22312 else if (type == VAR_FUNC || type == VAR_PARTIAL) |
22091 msg_putchar('*'); | 22313 msg_putchar('*'); |
22092 else if (type == VAR_LIST) | 22314 else if (type == VAR_LIST) |
22093 { | 22315 { |
22094 msg_putchar('['); | 22316 msg_putchar('['); |
22095 if (*string == '[') | 22317 if (*string == '[') |
22104 else | 22326 else |
22105 msg_putchar(' '); | 22327 msg_putchar(' '); |
22106 | 22328 |
22107 msg_outtrans(string); | 22329 msg_outtrans(string); |
22108 | 22330 |
22109 if (type == VAR_FUNC) | 22331 if (type == VAR_FUNC || type == VAR_PARTIAL) |
22110 msg_puts((char_u *)"()"); | 22332 msg_puts((char_u *)"()"); |
22111 if (*first) | 22333 if (*first) |
22112 { | 22334 { |
22113 msg_clr_eos(); | 22335 msg_clr_eos(); |
22114 *first = FALSE; | 22336 *first = FALSE; |
22136 EMSG2(_(e_illvar), name); | 22358 EMSG2(_(e_illvar), name); |
22137 return; | 22359 return; |
22138 } | 22360 } |
22139 v = find_var_in_ht(ht, 0, varname, TRUE); | 22361 v = find_var_in_ht(ht, 0, varname, TRUE); |
22140 | 22362 |
22141 if (tv->v_type == VAR_FUNC && var_check_func_name(name, v == NULL)) | 22363 if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) |
22364 && var_check_func_name(name, v == NULL)) | |
22142 return; | 22365 return; |
22143 | 22366 |
22144 if (v != NULL) | 22367 if (v != NULL) |
22145 { | 22368 { |
22146 /* existing variable, need to clear the value */ | 22369 /* existing variable, need to clear the value */ |
22381 to->vval.v_string = vim_strsave(from->vval.v_string); | 22604 to->vval.v_string = vim_strsave(from->vval.v_string); |
22382 if (from->v_type == VAR_FUNC) | 22605 if (from->v_type == VAR_FUNC) |
22383 func_ref(to->vval.v_string); | 22606 func_ref(to->vval.v_string); |
22384 } | 22607 } |
22385 break; | 22608 break; |
22609 case VAR_PARTIAL: | |
22610 if (from->vval.v_partial == NULL) | |
22611 to->vval.v_partial = NULL; | |
22612 else | |
22613 { | |
22614 to->vval.v_partial = from->vval.v_partial; | |
22615 ++to->vval.v_partial->pt_refcount; | |
22616 } | |
22617 break; | |
22386 case VAR_LIST: | 22618 case VAR_LIST: |
22387 if (from->vval.v_list == NULL) | 22619 if (from->vval.v_list == NULL) |
22388 to->vval.v_list = NULL; | 22620 to->vval.v_list = NULL; |
22389 else | 22621 else |
22390 { | 22622 { |
22435 { | 22667 { |
22436 case VAR_NUMBER: | 22668 case VAR_NUMBER: |
22437 case VAR_FLOAT: | 22669 case VAR_FLOAT: |
22438 case VAR_STRING: | 22670 case VAR_STRING: |
22439 case VAR_FUNC: | 22671 case VAR_FUNC: |
22672 case VAR_PARTIAL: | |
22440 case VAR_SPECIAL: | 22673 case VAR_SPECIAL: |
22441 case VAR_JOB: | 22674 case VAR_JOB: |
22442 case VAR_CHANNEL: | 22675 case VAR_CHANNEL: |
22443 copy_tv(from, to); | 22676 copy_tv(from, to); |
22444 break; | 22677 break; |
23413 char_u *end; | 23646 char_u *end; |
23414 int lead; | 23647 int lead; |
23415 char_u sid_buf[20]; | 23648 char_u sid_buf[20]; |
23416 int len; | 23649 int len; |
23417 lval_T lv; | 23650 lval_T lv; |
23651 partial_T *partial; | |
23418 | 23652 |
23419 if (fdp != NULL) | 23653 if (fdp != NULL) |
23420 vim_memset(fdp, 0, sizeof(funcdict_T)); | 23654 vim_memset(fdp, 0, sizeof(funcdict_T)); |
23421 start = *pp; | 23655 start = *pp; |
23422 | 23656 |
23497 | 23731 |
23498 /* Check if the name is a Funcref. If so, use the value. */ | 23732 /* Check if the name is a Funcref. If so, use the value. */ |
23499 if (lv.ll_exp_name != NULL) | 23733 if (lv.ll_exp_name != NULL) |
23500 { | 23734 { |
23501 len = (int)STRLEN(lv.ll_exp_name); | 23735 len = (int)STRLEN(lv.ll_exp_name); |
23502 name = deref_func_name(lv.ll_exp_name, &len, flags & TFN_NO_AUTOLOAD); | 23736 name = deref_func_name(lv.ll_exp_name, &len, &partial, |
23737 flags & TFN_NO_AUTOLOAD); | |
23503 if (name == lv.ll_exp_name) | 23738 if (name == lv.ll_exp_name) |
23504 name = NULL; | 23739 name = NULL; |
23505 } | 23740 } |
23506 else | 23741 else |
23507 { | 23742 { |
23508 len = (int)(end - *pp); | 23743 len = (int)(end - *pp); |
23509 name = deref_func_name(*pp, &len, flags & TFN_NO_AUTOLOAD); | 23744 name = deref_func_name(*pp, &len, &partial, flags & TFN_NO_AUTOLOAD); |
23510 if (name == *pp) | 23745 if (name == *pp) |
23511 name = NULL; | 23746 name = NULL; |
23512 } | 23747 } |
23513 if (name != NULL) | 23748 if (name != NULL) |
23514 { | 23749 { |
25109 case VAR_LIST: s = "LIS"; break; | 25344 case VAR_LIST: s = "LIS"; break; |
25110 case VAR_SPECIAL: s = "XPL"; break; | 25345 case VAR_SPECIAL: s = "XPL"; break; |
25111 | 25346 |
25112 case VAR_UNKNOWN: | 25347 case VAR_UNKNOWN: |
25113 case VAR_FUNC: | 25348 case VAR_FUNC: |
25349 case VAR_PARTIAL: | |
25114 case VAR_JOB: | 25350 case VAR_JOB: |
25115 case VAR_CHANNEL: | 25351 case VAR_CHANNEL: |
25116 continue; | 25352 continue; |
25117 } | 25353 } |
25118 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); | 25354 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); |