comparison src/userfunc.c @ 17606:ff097edaae89 v8.1.1800

patch 8.1.1800: function call functions have too many arguments commit https://github.com/vim/vim/commit/c6538bcc1cdd1fb83732f22fdc69bd9bb66f968a Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 3 18:17:11 2019 +0200 patch 8.1.1800: function call functions have too many arguments Problem: Function call functions have too many arguments. Solution: Pass values in a funcexe_T struct.
author Bram Moolenaar <Bram@vim.org>
date Sat, 03 Aug 2019 18:30:07 +0200
parents 9088fafff9b3
children e259d11e2900
comparison
equal deleted inserted replaced
17605:bb1b495f4e05 17606:ff097edaae89
430 get_func_tv( 430 get_func_tv(
431 char_u *name, // name of the function 431 char_u *name, // name of the function
432 int len, // length of "name" or -1 to use strlen() 432 int len, // length of "name" or -1 to use strlen()
433 typval_T *rettv, 433 typval_T *rettv,
434 char_u **arg, // argument, pointing to the '(' 434 char_u **arg, // argument, pointing to the '('
435 linenr_T firstline, // first line of range 435 funcexe_T *funcexe) // various values
436 linenr_T lastline, // last line of range
437 int *doesrange, // return: function handled range
438 int evaluate,
439 partial_T *partial, // for extra arguments
440 dict_T *selfdict) // Dictionary for "self"
441 { 436 {
442 char_u *argp; 437 char_u *argp;
443 int ret = OK; 438 int ret = OK;
444 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ 439 typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */
445 int argcount = 0; /* number of arguments found */ 440 int argcount = 0; /* number of arguments found */
446 441
447 /* 442 /*
448 * Get the arguments. 443 * Get the arguments.
449 */ 444 */
450 argp = *arg; 445 argp = *arg;
451 while (argcount < MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) 446 while (argcount < MAX_FUNC_ARGS - (funcexe->partial == NULL ? 0
447 : funcexe->partial->pt_argc))
452 { 448 {
453 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 449 argp = skipwhite(argp + 1); /* skip the '(' or ',' */
454 if (*argp == ')' || *argp == ',' || *argp == NUL) 450 if (*argp == ')' || *argp == ',' || *argp == NUL)
455 break; 451 break;
456 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 452 if (eval1(&argp, &argvars[argcount], funcexe->evaluate) == FAIL)
457 { 453 {
458 ret = FAIL; 454 ret = FAIL;
459 break; 455 break;
460 } 456 }
461 ++argcount; 457 ++argcount;
481 if (ga_grow(&funcargs, 1) == OK) 477 if (ga_grow(&funcargs, 1) == OK)
482 ((typval_T **)funcargs.ga_data)[funcargs.ga_len++] = 478 ((typval_T **)funcargs.ga_data)[funcargs.ga_len++] =
483 &argvars[i]; 479 &argvars[i];
484 } 480 }
485 481
486 ret = call_func(name, len, rettv, argcount, argvars, NULL, 482 ret = call_func(name, len, rettv, argcount, argvars, funcexe);
487 firstline, lastline, doesrange, evaluate, partial, selfdict);
488 483
489 funcargs.ga_len -= i; 484 funcargs.ga_len -= i;
490 } 485 }
491 else if (!aborting()) 486 else if (!aborting())
492 { 487 {
1414 typval_T *rettv) 1409 typval_T *rettv)
1415 { 1410 {
1416 listitem_T *item; 1411 listitem_T *item;
1417 typval_T argv[MAX_FUNC_ARGS + 1]; 1412 typval_T argv[MAX_FUNC_ARGS + 1];
1418 int argc = 0; 1413 int argc = 0;
1419 int dummy;
1420 int r = 0; 1414 int r = 0;
1421 1415
1422 for (item = args->vval.v_list->lv_first; item != NULL; 1416 for (item = args->vval.v_list->lv_first; item != NULL;
1423 item = item->li_next) 1417 item = item->li_next)
1424 { 1418 {
1432 */ 1426 */
1433 copy_tv(&item->li_tv, &argv[argc++]); 1427 copy_tv(&item->li_tv, &argv[argc++]);
1434 } 1428 }
1435 1429
1436 if (item == NULL) 1430 if (item == NULL)
1437 r = call_func(name, -1, rettv, argc, argv, NULL, 1431 {
1438 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 1432 funcexe_T funcexe;
1439 &dummy, TRUE, partial, selfdict); 1433
1434 funcexe.argv_func = NULL;
1435 funcexe.firstline = curwin->w_cursor.lnum;
1436 funcexe.lastline = curwin->w_cursor.lnum;
1437 funcexe.doesrange = NULL;
1438 funcexe.evaluate = TRUE;
1439 funcexe.partial = partial;
1440 funcexe.selfdict = selfdict;
1441 r = call_func(name, -1, rettv, argc, argv, &funcexe);
1442 }
1440 1443
1441 /* Free the arguments. */ 1444 /* Free the arguments. */
1442 while (argc > 0) 1445 while (argc > 0)
1443 clear_tv(&argv[--argc]); 1446 clear_tv(&argv[--argc]);
1444 1447
1452 call_callback( 1455 call_callback(
1453 callback_T *callback, 1456 callback_T *callback,
1454 int len, // length of "name" or -1 to use strlen() 1457 int len, // length of "name" or -1 to use strlen()
1455 typval_T *rettv, // return value goes here 1458 typval_T *rettv, // return value goes here
1456 int argcount, // number of "argvars" 1459 int argcount, // number of "argvars"
1457 typval_T *argvars, // vars for arguments, must have "argcount" 1460 typval_T *argvars) // vars for arguments, must have "argcount"
1458 // PLUS ONE elements! 1461 // PLUS ONE elements!
1459 int (* argv_func)(int, typval_T *, int), 1462 {
1460 // function to fill in argvars 1463 funcexe_T funcexe;
1461 linenr_T firstline, // first line of range 1464
1462 linenr_T lastline, // last line of range 1465 vim_memset(&funcexe, 0, sizeof(funcexe));
1463 int *doesrange, // return: function handled range 1466 funcexe.evaluate = TRUE;
1464 int evaluate, 1467 funcexe.partial = callback->cb_partial;
1465 dict_T *selfdict) // Dictionary for "self"
1466 {
1467 return call_func(callback->cb_name, len, rettv, argcount, argvars, 1468 return call_func(callback->cb_name, len, rettv, argcount, argvars,
1468 argv_func, firstline, lastline, doesrange, evaluate, 1469 &funcexe);
1469 callback->cb_partial, selfdict);
1470 } 1470 }
1471 1471
1472 /* 1472 /*
1473 * Call a function with its resolved parameters 1473 * Call a function with its resolved parameters
1474 *
1475 * "argv_func", when not NULL, can be used to fill in arguments only when the
1476 * invoked function uses them. It is called like this:
1477 * new_argcount = argv_func(current_argcount, argv, called_func_argcount)
1478 * 1474 *
1479 * Return FAIL when the function can't be called, OK otherwise. 1475 * Return FAIL when the function can't be called, OK otherwise.
1480 * Also returns OK when an error was encountered while executing the function. 1476 * Also returns OK when an error was encountered while executing the function.
1481 */ 1477 */
1482 int 1478 int
1485 int len, // length of "name" or -1 to use strlen() 1481 int len, // length of "name" or -1 to use strlen()
1486 typval_T *rettv, // return value goes here 1482 typval_T *rettv, // return value goes here
1487 int argcount_in, // number of "argvars" 1483 int argcount_in, // number of "argvars"
1488 typval_T *argvars_in, // vars for arguments, must have "argcount" 1484 typval_T *argvars_in, // vars for arguments, must have "argcount"
1489 // PLUS ONE elements! 1485 // PLUS ONE elements!
1490 int (* argv_func)(int, typval_T *, int), 1486 funcexe_T *funcexe) // more arguments
1491 // function to fill in argvars
1492 linenr_T firstline, // first line of range
1493 linenr_T lastline, // last line of range
1494 int *doesrange, // return: function handled range
1495 int evaluate,
1496 partial_T *partial, // optional, can be NULL
1497 dict_T *selfdict_in) // Dictionary for "self"
1498 { 1487 {
1499 int ret = FAIL; 1488 int ret = FAIL;
1500 int error = ERROR_NONE; 1489 int error = ERROR_NONE;
1501 int i; 1490 int i;
1502 ufunc_T *fp; 1491 ufunc_T *fp;
1504 char_u *tofree = NULL; 1493 char_u *tofree = NULL;
1505 char_u *fname; 1494 char_u *fname;
1506 char_u *name; 1495 char_u *name;
1507 int argcount = argcount_in; 1496 int argcount = argcount_in;
1508 typval_T *argvars = argvars_in; 1497 typval_T *argvars = argvars_in;
1509 dict_T *selfdict = selfdict_in; 1498 dict_T *selfdict = funcexe->selfdict;
1510 typval_T argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */ 1499 typval_T argv[MAX_FUNC_ARGS + 1]; /* used when "partial" is not NULL */
1511 int argv_clear = 0; 1500 int argv_clear = 0;
1501 partial_T *partial = funcexe->partial;
1512 1502
1513 // Make a copy of the name, if it comes from a funcref variable it could 1503 // Make a copy of the name, if it comes from a funcref variable it could
1514 // be changed or deleted in the called function. 1504 // be changed or deleted in the called function.
1515 name = len > 0 ? vim_strnsave(funcname, len) : vim_strsave(funcname); 1505 name = len > 0 ? vim_strnsave(funcname, len) : vim_strsave(funcname);
1516 if (name == NULL) 1506 if (name == NULL)
1517 return ret; 1507 return ret;
1518 1508
1519 fname = fname_trans_sid(name, fname_buf, &tofree, &error); 1509 fname = fname_trans_sid(name, fname_buf, &tofree, &error);
1520 1510
1521 *doesrange = FALSE; 1511 if (funcexe->doesrange != NULL)
1512 *funcexe->doesrange = FALSE;
1522 1513
1523 if (partial != NULL) 1514 if (partial != NULL)
1524 { 1515 {
1525 /* When the function has a partial with a dict and there is a dict 1516 /* When the function has a partial with a dict and there is a dict
1526 * argument, use the dict argument. That is backwards compatible. 1517 * argument, use the dict argument. That is backwards compatible.
1527 * When the dict was bound explicitly use the one from the partial. */ 1518 * When the dict was bound explicitly use the one from the partial. */
1528 if (partial->pt_dict != NULL 1519 if (partial->pt_dict != NULL && (selfdict == NULL || !partial->pt_auto))
1529 && (selfdict_in == NULL || !partial->pt_auto))
1530 selfdict = partial->pt_dict; 1520 selfdict = partial->pt_dict;
1531 if (error == ERROR_NONE && partial->pt_argc > 0) 1521 if (error == ERROR_NONE && partial->pt_argc > 0)
1532 { 1522 {
1533 for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear) 1523 for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear)
1534 copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]); 1524 copy_tv(&partial->pt_argv[argv_clear], &argv[argv_clear]);
1540 } 1530 }
1541 1531
1542 /* 1532 /*
1543 * Execute the function if executing and no errors were detected. 1533 * Execute the function if executing and no errors were detected.
1544 */ 1534 */
1545 if (!evaluate) 1535 if (!funcexe->evaluate)
1546 { 1536 {
1547 // Not evaluating, which means the return value is unknown. This 1537 // Not evaluating, which means the return value is unknown. This
1548 // matters for giving error messages. 1538 // matters for giving error messages.
1549 rettv->v_type = VAR_UNKNOWN; 1539 rettv->v_type = VAR_UNKNOWN;
1550 } 1540 }
1588 1578
1589 if (fp != NULL && (fp->uf_flags & FC_DELETED)) 1579 if (fp != NULL && (fp->uf_flags & FC_DELETED))
1590 error = ERROR_DELETED; 1580 error = ERROR_DELETED;
1591 else if (fp != NULL) 1581 else if (fp != NULL)
1592 { 1582 {
1593 if (argv_func != NULL) 1583 if (funcexe->argv_func != NULL)
1594 argcount = argv_func(argcount, argvars, fp->uf_args.ga_len); 1584 argcount = funcexe->argv_func(argcount, argvars,
1595 1585 fp->uf_args.ga_len);
1596 if (fp->uf_flags & FC_RANGE) 1586
1597 *doesrange = TRUE; 1587 if (fp->uf_flags & FC_RANGE && funcexe->doesrange != NULL)
1588 *funcexe->doesrange = TRUE;
1598 if (argcount < fp->uf_args.ga_len - fp->uf_def_args.ga_len) 1589 if (argcount < fp->uf_args.ga_len - fp->uf_def_args.ga_len)
1599 error = ERROR_TOOFEW; 1590 error = ERROR_TOOFEW;
1600 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 1591 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len)
1601 error = ERROR_TOOMANY; 1592 error = ERROR_TOOMANY;
1602 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 1593 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
1619 saveRedobuff(&save_redo); 1610 saveRedobuff(&save_redo);
1620 did_save_redo = TRUE; 1611 did_save_redo = TRUE;
1621 } 1612 }
1622 ++fp->uf_calls; 1613 ++fp->uf_calls;
1623 call_user_func(fp, argcount, argvars, rettv, 1614 call_user_func(fp, argcount, argvars, rettv,
1624 firstline, lastline, 1615 funcexe->firstline, funcexe->lastline,
1625 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 1616 (fp->uf_flags & FC_DICT) ? selfdict : NULL);
1626 if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0) 1617 if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0)
1627 /* Function was unreferenced while being used, free it 1618 /* Function was unreferenced while being used, free it
1628 * now. */ 1619 * now. */
1629 func_clear_free(fp, FALSE); 1620 func_clear_free(fp, FALSE);
3110 } 3101 }
3111 else 3102 else
3112 lnum = eap->line1; 3103 lnum = eap->line1;
3113 for ( ; lnum <= eap->line2; ++lnum) 3104 for ( ; lnum <= eap->line2; ++lnum)
3114 { 3105 {
3106 funcexe_T funcexe;
3107
3115 if (!eap->skip && eap->addr_count > 0) 3108 if (!eap->skip && eap->addr_count > 0)
3116 { 3109 {
3117 if (lnum > curbuf->b_ml.ml_line_count) 3110 if (lnum > curbuf->b_ml.ml_line_count)
3118 { 3111 {
3119 // If the function deleted lines or switched to another buffer 3112 // If the function deleted lines or switched to another buffer
3124 curwin->w_cursor.lnum = lnum; 3117 curwin->w_cursor.lnum = lnum;
3125 curwin->w_cursor.col = 0; 3118 curwin->w_cursor.col = 0;
3126 curwin->w_cursor.coladd = 0; 3119 curwin->w_cursor.coladd = 0;
3127 } 3120 }
3128 arg = startarg; 3121 arg = startarg;
3129 if (get_func_tv(name, -1, &rettv, &arg, 3122
3130 eap->line1, eap->line2, &doesrange, 3123 funcexe.argv_func = NULL;
3131 !eap->skip, partial, fudi.fd_dict) == FAIL) 3124 funcexe.firstline = eap->line1;
3125 funcexe.lastline = eap->line2;
3126 funcexe.doesrange = &doesrange;
3127 funcexe.evaluate = !eap->skip;
3128 funcexe.partial = partial;
3129 funcexe.selfdict = fudi.fd_dict;
3130 if (get_func_tv(name, -1, &rettv, &arg, &funcexe) == FAIL)
3132 { 3131 {
3133 failed = TRUE; 3132 failed = TRUE;
3134 break; 3133 break;
3135 } 3134 }
3136 if (has_watchexpr()) 3135 if (has_watchexpr())