comparison src/vim9compile.c @ 24512:53871095bb65 v8.2.2796

patch 8.2.2796: Vim9: redir to variable does not accept an index Commit: https://github.com/vim/vim/commit/753bcf8c7d7cf7b9e1572a80cc513a67020814ac Author: Bram Moolenaar <Bram@vim.org> Date: Wed Apr 21 14:24:24 2021 +0200 patch 8.2.2796: Vim9: redir to variable does not accept an index Problem: Vim9: redir to variable does not accept an index. Solution: Make the index work.
author Bram Moolenaar <Bram@vim.org>
date Wed, 21 Apr 2021 14:30:04 +0200
parents b5786b4de9d1
children 056f954c6fd2
comparison
equal deleted inserted replaced
24511:2aaa71ea39fb 24512:53871095bb65
132 // Used by compile_lhs() to store information about the LHS of an assignment 132 // Used by compile_lhs() to store information about the LHS of an assignment
133 // and one argument of ":unlet" with an index. 133 // and one argument of ":unlet" with an index.
134 typedef struct { 134 typedef struct {
135 assign_dest_T lhs_dest; // type of destination 135 assign_dest_T lhs_dest; // type of destination
136 136
137 char_u *lhs_name; // allocated name including 137 char_u *lhs_name; // allocated name excluding the last
138 // "[expr]" or ".name". 138 // "[expr]" or ".name".
139 size_t lhs_varlen; // length of the variable without 139 size_t lhs_varlen; // length of the variable without
140 // "[expr]" or ".name" 140 // "[expr]" or ".name"
141 char_u *lhs_whole; // allocated name including the last
142 // "[expr]" or ".name" for :redir
143 size_t lhs_varlen_total; // length of the variable including
144 // any "[expr]" or ".name"
141 char_u *lhs_dest_end; // end of the destination, including 145 char_u *lhs_dest_end; // end of the destination, including
142 // "[expr]" or ".name". 146 // "[expr]" or ".name".
143 147
144 int lhs_has_index; // has "[expr]" or ".name" 148 int lhs_has_index; // has "[expr]" or ".name"
145 149
5843 if (is_decl && var_end == var_start + 2 && var_end[-1] == ':') 5847 if (is_decl && var_end == var_start + 2 && var_end[-1] == ':')
5844 --var_end; 5848 --var_end;
5845 5849
5846 // compute the length of the destination without "[expr]" or ".name" 5850 // compute the length of the destination without "[expr]" or ".name"
5847 lhs->lhs_varlen = var_end - var_start; 5851 lhs->lhs_varlen = var_end - var_start;
5852 lhs->lhs_varlen_total = lhs->lhs_varlen;
5848 lhs->lhs_name = vim_strnsave(var_start, lhs->lhs_varlen); 5853 lhs->lhs_name = vim_strnsave(var_start, lhs->lhs_varlen);
5849 if (lhs->lhs_name == NULL) 5854 if (lhs->lhs_name == NULL)
5850 return FAIL; 5855 return FAIL;
5851 5856
5852 if (lhs->lhs_dest_end > var_start + lhs->lhs_varlen) 5857 if (lhs->lhs_dest_end > var_start + lhs->lhs_varlen)
6071 // "ll[1][2]" the expression is "ll[1]" and "[2]" is the index. 6076 // "ll[1][2]" the expression is "ll[1]" and "[2]" is the index.
6072 for (;;) 6077 for (;;)
6073 { 6078 {
6074 p = skip_index(after); 6079 p = skip_index(after);
6075 if (*p != '[' && *p != '.') 6080 if (*p != '[' && *p != '.')
6081 {
6082 lhs->lhs_varlen_total = p - var_start;
6076 break; 6083 break;
6084 }
6077 after = p; 6085 after = p;
6078 } 6086 }
6079 if (after > var_start + lhs->lhs_varlen) 6087 if (after > var_start + lhs->lhs_varlen)
6080 { 6088 {
6081 lhs->lhs_varlen = after - var_start; 6089 lhs->lhs_varlen = after - var_start;
8590 8598
8591 static char_u * 8599 static char_u *
8592 compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx) 8600 compile_redir(char_u *line, exarg_T *eap, cctx_T *cctx)
8593 { 8601 {
8594 char_u *arg = eap->arg; 8602 char_u *arg = eap->arg;
8595 8603 lhs_T *lhs = &cctx->ctx_redir_lhs;
8596 if (cctx->ctx_redir_lhs.lhs_name != NULL) 8604
8605 if (lhs->lhs_name != NULL)
8597 { 8606 {
8598 if (STRNCMP(arg, "END", 3) == 0) 8607 if (STRNCMP(arg, "END", 3) == 0)
8599 { 8608 {
8600 if (cctx->ctx_redir_lhs.lhs_append) 8609 if (lhs->lhs_append)
8601 { 8610 {
8602 if (compile_load_lhs(&cctx->ctx_redir_lhs, 8611 if (compile_load_lhs(lhs, lhs->lhs_name, NULL, cctx) == FAIL)
8603 cctx->ctx_redir_lhs.lhs_name, NULL, cctx) == FAIL)
8604 return NULL; 8612 return NULL;
8605 if (cctx->ctx_redir_lhs.lhs_has_index) 8613 if (lhs->lhs_has_index)
8606 emsg("redir with index not implemented yet"); 8614 emsg("redir with index not implemented yet");
8607 } 8615 }
8608 8616
8609 // Gets the redirected text and put it on the stack, then store it 8617 // Gets the redirected text and put it on the stack, then store it
8610 // in the variable. 8618 // in the variable.
8611 generate_instr_type(cctx, ISN_REDIREND, &t_string); 8619 generate_instr_type(cctx, ISN_REDIREND, &t_string);
8612 8620
8613 if (cctx->ctx_redir_lhs.lhs_append) 8621 if (lhs->lhs_append)
8614 generate_instr_drop(cctx, ISN_CONCAT, 1); 8622 generate_instr_drop(cctx, ISN_CONCAT, 1);
8615 8623
8616 if (generate_store_lhs(cctx, &cctx->ctx_redir_lhs, -1) == FAIL) 8624 if (lhs->lhs_has_index)
8625 {
8626 // Use the info in "lhs" to store the value at the index in the
8627 // list or dict.
8628 if (compile_assign_unlet(lhs->lhs_whole, lhs, TRUE,
8629 &t_string, cctx) == FAIL)
8630 return NULL;
8631 }
8632 else if (generate_store_lhs(cctx, lhs, -1) == FAIL)
8617 return NULL; 8633 return NULL;
8618 8634
8619 VIM_CLEAR(cctx->ctx_redir_lhs.lhs_name); 8635 VIM_CLEAR(lhs->lhs_name);
8636 VIM_CLEAR(lhs->lhs_whole);
8620 return arg + 3; 8637 return arg + 3;
8621 } 8638 }
8622 emsg(_(e_cannot_nest_redir)); 8639 emsg(_(e_cannot_nest_redir));
8623 return NULL; 8640 return NULL;
8624 } 8641 }
8625 8642
8626 if (arg[0] == '=' && arg[1] == '>') 8643 if (arg[0] == '=' && arg[1] == '>')
8627 { 8644 {
8628 int append = FALSE; 8645 int append = FALSE;
8629 8646
8630 // redirect to a variable is compiled 8647 // redirect to a variable is compiled
8631 arg += 2; 8648 arg += 2;
8632 if (*arg == '>') 8649 if (*arg == '>')
8633 { 8650 {
8634 ++arg; 8651 ++arg;
8635 append = TRUE; 8652 append = TRUE;
8636 } 8653 }
8637 arg = skipwhite(arg); 8654 arg = skipwhite(arg);
8638 8655
8639 if (compile_assign_lhs(arg, &cctx->ctx_redir_lhs, CMD_redir, 8656 if (compile_assign_lhs(arg, lhs, CMD_redir,
8640 FALSE, FALSE, 1, cctx) == FAIL) 8657 FALSE, FALSE, 1, cctx) == FAIL)
8641 return NULL; 8658 return NULL;
8642 generate_instr(cctx, ISN_REDIRSTART); 8659 generate_instr(cctx, ISN_REDIRSTART);
8643 cctx->ctx_redir_lhs.lhs_append = append; 8660 lhs->lhs_append = append;
8644 8661 if (lhs->lhs_has_index)
8645 return arg + cctx->ctx_redir_lhs.lhs_varlen; 8662 {
8663 lhs->lhs_whole = vim_strnsave(arg, lhs->lhs_varlen_total);
8664 if (lhs->lhs_whole == NULL)
8665 return NULL;
8666 }
8667
8668 return arg + lhs->lhs_varlen_total;
8646 } 8669 }
8647 8670
8648 // other redirects are handled like at script level 8671 // other redirects are handled like at script level
8649 return compile_exec(line, eap, cctx); 8672 return compile_exec(line, eap, cctx);
8650 } 8673 }
9333 { 9356 {
9334 emsg(_(e_missing_redir_end)); 9357 emsg(_(e_missing_redir_end));
9335 ret = FAIL; 9358 ret = FAIL;
9336 } 9359 }
9337 vim_free(cctx.ctx_redir_lhs.lhs_name); 9360 vim_free(cctx.ctx_redir_lhs.lhs_name);
9361 vim_free(cctx.ctx_redir_lhs.lhs_whole);
9338 } 9362 }
9339 9363
9340 current_sctx = save_current_sctx; 9364 current_sctx = save_current_sctx;
9341 estack_compiling = save_estack_compiling; 9365 estack_compiling = save_estack_compiling;
9342 if (do_estack_push) 9366 if (do_estack_push)