To: vim-dev@vim.org Subject: Patch 6.1.254 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.1.254 Problem: exists("foo{bar}") does not work. ':unlet v{"a"}r' does not work. ":let v{a}r1 v{a}r2" does not work. ":func F{(1)}" does not work. ":delfunc F{" does not give an error message. ':delfunc F{"F"}' does not work. Solution: Support magic braces for the exists() argument. (Vince Negri) Check for trailing comments explicitly for ":unlet". Add support for magic braces in further arguments of ":let". Look for a parenthesis only after the function name. (Servatius Brandt) Also expand magic braces for "exists('*expr')". Give an error message for an invalid ":delfunc" argument. Allow quotes in the ":delfunc" argument. Files: src/eval.c, src/ex_cmds.h, src/ex_docmd.c *** ../vim61.253/src/eval.c Wed Nov 6 21:01:13 2002 --- src/eval.c Sun Nov 10 13:54:05 2002 *************** *** 339,345 **** static void set_var __ARGS((char_u *name, VAR varp)); static void copy_var __ARGS((VAR from, VAR to)); static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); ! static char_u *trans_function_name __ARGS((char_u **pp)); static int eval_fname_script __ARGS((char_u *p)); static int eval_fname_sid __ARGS((char_u *p)); static void list_func_head __ARGS((ufunc_T *fp)); --- 339,345 ---- static void set_var __ARGS((char_u *name, VAR varp)); static void copy_var __ARGS((VAR from, VAR to)); static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); ! static char_u *trans_function_name __ARGS((char_u **pp, int skip)); static int eval_fname_script __ARGS((char_u *p)); static int eval_fname_sid __ARGS((char_u *p)); static void list_func_head __ARGS((ufunc_T *fp)); *************** *** 347,352 **** --- 347,354 ---- static ufunc_T *find_func __ARGS((char_u *name)); static void call_func __ARGS((ufunc_T *fp, int argcount, VAR argvars, VAR retvar, linenr_T firstline, linenr_T lastline)); + /* Magic braces are always enabled, otherwise Vim scripts would not be + * portable. */ #define FEAT_MAGIC_BRACES #ifdef FEAT_MAGIC_BRACES *************** *** 582,587 **** --- 584,590 ---- char_u c1; char_u *retval = NULL; char_u *temp_result; + char_u *nextcmd = NULL; if (expr_end == NULL || in_end == NULL) return NULL; *************** *** 590,597 **** c1 = *in_end; *in_end = NUL; ! temp_result = eval_to_string(expr_start + 1, NULL); ! if (temp_result != NULL) { retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) + (in_end - expr_end) + 1)); --- 593,600 ---- c1 = *in_end; *in_end = NUL; ! temp_result = eval_to_string(expr_start + 1, &nextcmd); ! if (temp_result != NULL && nextcmd == NULL) { retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) + (in_end - expr_end) + 1)); *************** *** 602,610 **** STRCAT(retval, temp_result); STRCAT(retval, expr_end + 1); } - - vim_free(temp_result); } *in_end = c1; /* put char back for error messages */ *expr_start = '{'; --- 605,612 ---- STRCAT(retval, temp_result); STRCAT(retval, expr_end + 1); } } + vim_free(temp_result); *in_end = c1; /* put char back for error messages */ *expr_start = '{'; *************** *** 643,649 **** VAR varp; var retvar; char_u *p; ! int c1, c2; int i; expr = vim_strchr(arg, '='); --- 645,651 ---- VAR varp; var retvar; char_u *p; ! int c1 = 0, c2; int i; expr = vim_strchr(arg, '='); *************** *** 672,701 **** } else { /* * List variables. */ while (!ends_excmd(*arg)) { ! for (p = arg; eval_isnamec(*p); ++p) ! ; ! if (!vim_iswhite(*p) && !ends_excmd(*p)) { EMSG(_(e_trailing)); break; } ! if (!eap->skip) { ! c1 = *p; ! *p = NUL; ! i = find_vim_var(arg, (int)(p - arg)); if (i >= 0) list_vim_var(i); else { varp = find_var(arg, FALSE); if (varp == NULL) EMSG2(_("E106: Unknown variable: \"%s\""), arg); else { name = vim_strchr(arg, ':'); --- 674,735 ---- } else { + int error = FALSE; + /* * List variables. */ while (!ends_excmd(*arg)) { ! char_u *expr_start; ! char_u *expr_end; ! char_u *name_end; ! char_u *temp_string = NULL; ! int arg_len; ! ! /* Find the end of the name. */ ! name_end = find_name_end(arg, &expr_start, &expr_end); ! ! if (!vim_iswhite(*name_end) && !ends_excmd(*name_end)) { EMSG(_(e_trailing)); break; } ! if (!error && !eap->skip) { ! #ifdef FEAT_MAGIC_BRACES ! if (expr_start != NULL) ! { ! temp_string = make_expanded_name(arg, expr_start, ! expr_end, name_end); ! if (temp_string == NULL) ! { ! EMSG2(_(e_invarg2), arg); ! break; ! } ! arg = temp_string; ! arg_len = STRLEN(temp_string); ! } ! else ! #endif ! { ! c1 = *name_end; ! *name_end = NUL; ! arg_len = (int)(name_end - arg); ! } ! i = find_vim_var(arg, arg_len); if (i >= 0) list_vim_var(i); else { varp = find_var(arg, FALSE); if (varp == NULL) + { + /* Skip further arguments but do continue to + * search for a trailing command. */ EMSG2(_("E106: Unknown variable: \"%s\""), arg); + error = TRUE; + } else { name = vim_strchr(arg, ':'); *************** *** 718,726 **** list_one_var(varp, (char_u *)""); } } ! *p = c1; } ! arg = skipwhite(p); } } eap->nextcmd = check_nextcmd(arg); --- 752,765 ---- list_one_var(varp, (char_u *)""); } } ! #ifdef FEAT_MAGIC_BRACES ! if (expr_start != NULL) ! vim_free(temp_string); ! else ! #endif ! *name_end = c1; } ! arg = skipwhite(name_end); } } eap->nextcmd = check_nextcmd(arg); *************** *** 1035,1084 **** char_u cc; char_u *expr_start; char_u *expr_end; do { - /* Find the end of the name. */ name_end = find_name_end(arg, &expr_start, &expr_end); ! #ifdef FEAT_MAGIC_BRACES ! if (expr_start != NULL) { ! char_u *temp_string; ! temp_string = make_expanded_name(arg, expr_start, ! expr_end, name_end); ! if (temp_string == NULL) ! EMSG2(_(e_invarg2), arg); ! else { ! if (do_unlet(temp_string) == FAIL && !eap->forceit) { ! EMSG2(_("E108: No such variable: \"%s\""), temp_string); vim_free(temp_string); - break; } - vim_free(temp_string); } ! } ! else #endif - { - cc = *name_end; - *name_end = NUL; - - if (do_unlet(arg) == FAIL && !eap->forceit) { *name_end = cc; - EMSG2(_("E108: No such variable: \"%s\""), arg); - break; } - - *name_end = cc; } arg = skipwhite(name_end); ! } while (*arg != NUL); } /* --- 1074,1132 ---- char_u cc; char_u *expr_start; char_u *expr_end; + int error = FALSE; do { /* Find the end of the name. */ name_end = find_name_end(arg, &expr_start, &expr_end); ! if (!vim_iswhite(*name_end) && !ends_excmd(*name_end)) { ! EMSG(_(e_trailing)); ! break; ! } ! if (!error && !eap->skip) ! { ! #ifdef FEAT_MAGIC_BRACES ! if (expr_start != NULL) { ! char_u *temp_string; ! ! temp_string = make_expanded_name(arg, expr_start, ! expr_end, name_end); ! if (temp_string == NULL) ! EMSG2(_(e_invarg2), arg); ! else { ! if (do_unlet(temp_string) == FAIL && !eap->forceit) ! { ! EMSG2(_("E108: No such variable: \"%s\""), temp_string); ! error = TRUE; ! } vim_free(temp_string); } } ! else #endif { + cc = *name_end; + *name_end = NUL; + + if (do_unlet(arg) == FAIL && !eap->forceit) + { + EMSG2(_("E108: No such variable: \"%s\""), arg); + error = TRUE; + } + *name_end = cc; } } arg = skipwhite(name_end); ! } while (!ends_excmd(*arg)); ! ! eap->nextcmd = check_nextcmd(arg); } /* *************** *** 3396,3402 **** char_u *p; char_u *name; int n = FALSE; ! int len; p = get_var_string(&argvars[0]); if (*p == '$') /* environment variable */ --- 3444,3450 ---- char_u *p; char_u *name; int n = FALSE; ! int len = 0; p = get_var_string(&argvars[0]); if (*p == '$') /* environment variable */ *************** *** 3418,3434 **** else if (*p == '*') /* internal or user defined function */ { ++p; ! if (ASCII_ISUPPER(*p) || *p == '<' || (*p == 's' && p[1] == ':')) { ! p = trans_function_name(&p); ! if (p != NULL) ! { n = (find_func(p) != NULL); ! vim_free(p); ! } } - else if (ASCII_ISLOWER(*p)) - n = (find_internal_func(p) >= 0); } else if (*p == ':') { --- 3466,3480 ---- else if (*p == '*') /* internal or user defined function */ { ++p; ! p = trans_function_name(&p, FALSE); ! if (p != NULL) { ! if (ASCII_ISUPPER(*p) || p[0] == K_SPECIAL) n = (find_func(p) != NULL); ! else if (ASCII_ISLOWER(*p)) ! n = (find_internal_func(p) >= 0); ! vim_free(p); } } else if (*p == ':') { *************** *** 3447,3456 **** } else /* internal variable */ { name = p; ! len = get_id_len(&p); if (len != 0) n = (get_var_var(name, len, NULL) == OK); } retvar->var_val.var_number = n; --- 3493,3529 ---- } else /* internal variable */ { + #ifdef FEAT_MAGIC_BRACES + char_u *expr_start; + char_u *expr_end; + char_u *temp_string = NULL; + char_u *s; + #endif name = p; ! ! #ifdef FEAT_MAGIC_BRACES ! /* Find the end of the name. */ ! s = find_name_end(name, &expr_start, &expr_end); ! if (expr_start != NULL) ! { ! ++emsg_skip; ! temp_string = make_expanded_name(name, expr_start, expr_end, s); ! --emsg_skip; ! if (temp_string != NULL) ! { ! len = STRLEN(temp_string); ! name = temp_string; ! } ! } ! #endif ! if (len == 0) ! len = get_id_len(&p); if (len != 0) n = (get_var_var(name, len, NULL) == OK); + + #ifdef FEAT_MAGIC_BRACES + vim_free(temp_string); + #endif } retvar->var_val.var_number = n; *************** *** 7633,7656 **** /* * ":function" without argument: list functions. */ ! if (*eap->arg == NUL) { if (!eap->skip) for (fp = firstfunc; fp != NULL && !got_int; fp = fp->next) list_func_head(fp); return; } p = eap->arg; ! name = trans_function_name(&p); if (name == NULL && !eap->skip) return; /* * ":function func" with only function name: list function. */ ! if (vim_strchr(eap->arg, '(') == NULL) { if (!eap->skip) { fp = find_func(name); --- 7706,7738 ---- /* * ":function" without argument: list functions. */ ! if (ends_excmd(*eap->arg)) { if (!eap->skip) for (fp = firstfunc; fp != NULL && !got_int; fp = fp->next) list_func_head(fp); + eap->nextcmd = check_nextcmd(eap->arg); return; } p = eap->arg; ! name = trans_function_name(&p, eap->skip); if (name == NULL && !eap->skip) return; /* * ":function func" with only function name: list function. */ ! if (vim_strchr(p, '(') == NULL) { + if (!ends_excmd(*skipwhite(p))) + { + EMSG(_(e_trailing)); + goto erret_name; + } + eap->nextcmd = check_nextcmd(p); + if (eap->nextcmd != NULL) + *p = NUL; if (!eap->skip) { fp = find_func(name); *************** *** 7919,7926 **** * Advances "pp" to just after the function name (if no error). */ static char_u * ! trans_function_name(pp) char_u **pp; { char_u *name; char_u *start; --- 8001,8009 ---- * Advances "pp" to just after the function name (if no error). */ static char_u * ! trans_function_name(pp, skip) char_u **pp; + int skip; /* only find the end, don't evaluate */ { char_u *name; char_u *start; *************** *** 7936,7962 **** lead = eval_fname_script(start); if (lead > 0) start += lead; - else if (!ASCII_ISUPPER(*start)) - { - EMSG2(_("E128: Function name must start with a capital: %s"), start); - return NULL; - } end = find_name_end(start, &expr_start, &expr_end); if (end == start) { ! EMSG(_("E129: Function name required")); return NULL; } ! if (expr_start != NULL) { /* expand magic curlies */ temp_string = make_expanded_name(start, expr_start, expr_end, end); if (temp_string == NULL) return NULL; start = temp_string; len = (int)STRLEN(temp_string); } else len = (int)(end - start); /* --- 8019,8046 ---- lead = eval_fname_script(start); if (lead > 0) start += lead; end = find_name_end(start, &expr_start, &expr_end); if (end == start) { ! if (!skip) ! EMSG(_("E129: Function name required")); return NULL; } ! #ifdef FEAT_MAGIC_BRACES ! if (expr_start != NULL && !skip) { /* expand magic curlies */ temp_string = make_expanded_name(start, expr_start, expr_end, end); if (temp_string == NULL) + { + EMSG2(_(e_invarg2), start); return NULL; + } start = temp_string; len = (int)STRLEN(temp_string); } else + #endif len = (int)(end - start); /* *************** *** 7964,7970 **** * Accept name() inside a script, translate into 123_name(). * Accept 123_name() outside a script. */ ! if (lead > 0) { lead = 3; if (eval_fname_sid(*pp)) /* If it's "" */ --- 8048,8056 ---- * Accept name() inside a script, translate into 123_name(). * Accept 123_name() outside a script. */ ! if (skip) ! /* do nothing */; ! else if (lead > 0) { lead = 3; if (eval_fname_sid(*pp)) /* If it's "" */ *************** *** 7979,7985 **** --- 8065,8079 ---- } } else + { + if (!ASCII_ISUPPER(*start)) + { + EMSG2(_("E128: Function name must start with a capital: %s"), + start); + return NULL; + } lead = 0; + } name = alloc((unsigned)(len + lead + 1)); if (name != NULL) { *************** *** 8139,8184 **** ex_delfunction(eap) exarg_T *eap; { ! ufunc_T *fp, *pfp; char_u *p; char_u *name; p = eap->arg; ! name = trans_function_name(&p); if (name == NULL) return; ! fp = find_func(name); ! vim_free(name); ! ! if (fp == NULL) { ! EMSG2(_("E130: Undefined function: %s"), eap->arg); ! return; ! } ! if (fp->calls) ! { ! EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); return; } ! /* clear this function */ ! vim_free(fp->name); ! ga_clear_strings(&(fp->args)); ! ga_clear_strings(&(fp->lines)); ! /* remove the function from the function list */ ! if (firstfunc == fp) ! firstfunc = fp->next; ! else { ! for (pfp = firstfunc; pfp != NULL; pfp = pfp->next) ! if (pfp->next == fp) ! { ! pfp->next = fp->next; ! break; ! } } - vim_free(fp); } /* --- 8233,8291 ---- ex_delfunction(eap) exarg_T *eap; { ! ufunc_T *fp = NULL, *pfp; char_u *p; char_u *name; p = eap->arg; ! name = trans_function_name(&p, eap->skip); if (name == NULL) return; ! if (!ends_excmd(*skipwhite(p))) { ! EMSG(_(e_trailing)); return; } + eap->nextcmd = check_nextcmd(p); + if (eap->nextcmd != NULL) + *p = NUL; ! if (!eap->skip) ! fp = find_func(name); ! vim_free(name); ! if (!eap->skip) { ! if (fp == NULL) ! { ! EMSG2(_("E130: Undefined function: %s"), eap->arg); ! return; ! } ! if (fp->calls) ! { ! EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); ! return; ! } ! ! /* clear this function */ ! vim_free(fp->name); ! ga_clear_strings(&(fp->args)); ! ga_clear_strings(&(fp->lines)); ! ! /* remove the function from the function list */ ! if (firstfunc == fp) ! firstfunc = fp->next; ! else ! { ! for (pfp = firstfunc; pfp != NULL; pfp = pfp->next) ! if (pfp->next == fp) ! { ! pfp->next = fp->next; ! break; ! } ! } ! vim_free(fp); } } /* *************** *** 8256,8261 **** --- 8363,8388 ---- ++no_wait_return; msg_scroll = TRUE; /* always scroll up, don't overwrite */ smsg((char_u *)_("calling %s"), sourcing_name); + if (p_verbose >= 14) + { + int i; + + msg_puts((char_u *)"("); + for (i = 0; i < argcount; ++i) + { + if (i > 0) + msg_puts((char_u *)", "); + if (argvars[i].var_type == VAR_NUMBER) + msg_outnum((long)argvars[i].var_val.var_number); + else + { + msg_puts((char_u *)"\""); + msg_puts(get_var_string(&argvars[i])); + msg_puts((char_u *)"\""); + } + } + msg_puts((char_u *)")"); + } msg_puts((char_u *)"\n"); /* don't overwrite this either */ cmdline_row = msg_row; --no_wait_return; *** ../vim61.253/src/ex_cmds.h Sun Jun 9 18:28:25 2002 --- src/ex_cmds.h Fri Oct 25 19:38:25 2002 *************** *** 273,279 **** EX(CMD_delcommand, "delcommand", ex_delcommand, NEEDARG|WORD1|TRLBAR|CMDWIN), EX(CMD_delfunction, "delfunction", ex_delfunction, ! NEEDARG|WORD1|TRLBAR|CMDWIN), EX(CMD_display, "display", ex_display, EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN), EX(CMD_diffupdate, "diffupdate", ex_diffupdate, --- 273,279 ---- EX(CMD_delcommand, "delcommand", ex_delcommand, NEEDARG|WORD1|TRLBAR|CMDWIN), EX(CMD_delfunction, "delfunction", ex_delfunction, ! NEEDARG|WORD1|CMDWIN), EX(CMD_display, "display", ex_display, EXTRA|NOTRLCOM|TRLBAR|SBOXOK|CMDWIN), EX(CMD_diffupdate, "diffupdate", ex_diffupdate, *************** *** 771,777 **** EX(CMD_unhide, "unhide", ex_buffer_all, RANGE|NOTADR|COUNT|TRLBAR), EX(CMD_unlet, "unlet", ex_unlet, ! BANG|EXTRA|NEEDARG|TRLBAR|SBOXOK|CMDWIN), EX(CMD_unmap, "unmap", ex_unmap, BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_unmenu, "unmenu", ex_menu, --- 771,777 ---- EX(CMD_unhide, "unhide", ex_buffer_all, RANGE|NOTADR|COUNT|TRLBAR), EX(CMD_unlet, "unlet", ex_unlet, ! BANG|EXTRA|NEEDARG|SBOXOK|CMDWIN), EX(CMD_unmap, "unmap", ex_unmap, BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_unmenu, "unmenu", ex_menu, *** ../vim61.253/src/ex_docmd.c Mon Nov 11 21:25:36 2002 --- src/ex_docmd.c Thu Nov 7 21:17:23 2002 *************** *** 1775,1780 **** --- 1775,1781 ---- case CMD_browse: case CMD_call: case CMD_confirm: + case CMD_delfunction: case CMD_djump: case CMD_dlist: case CMD_dsearch: *************** *** 1803,1808 **** --- 1804,1810 ---- case CMD_syntax: case CMD_tilde: case CMD_topleft: + case CMD_unlet: case CMD_verbose: case CMD_vertical: break; *** ../vim61.253/src/version.c Mon Nov 11 21:34:16 2002 --- src/version.c Mon Nov 11 21:38:40 2002 *************** *** 608,609 **** --- 608,611 ---- { /* Add new patch number below this line */ + /**/ + 254, /**/ -- hundred-and-one symptoms of being an internet addict: 2. You kiss your girlfriend's home page. /// Bram Moolenaar -- Bram@moolenaar.net -- http://www.moolenaar.net \\\ /// Creator of Vim - Vi IMproved -- http://www.vim.org \\\ \\\ Project leader for A-A-P -- http://www.a-a-p.org /// \\\ Lord Of The Rings helps Uganda - http://iccf-holland.org/lotr.html ///