comparison src/vim9script.c @ 21146:465d6e40e79c v8.2.1124

patch 8.2.1124: Vim9: no line break allowed in :import command Commit: https://github.com/vim/vim/commit/1c991144c502ade477e1a32fdfd0f78b6299fdc7 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jul 4 13:15:31 2020 +0200 patch 8.2.1124: Vim9: no line break allowed in :import command Problem: Vim9: no line break allowed in :import command. Solution: Skip over line breaks.
author Bram Moolenaar <Bram@vim.org>
date Sat, 04 Jul 2020 13:30:04 +0200
parents 4d844a65183d
children 667192c5938b
comparison
equal deleted inserted replaced
21145:9761ed6ea124 21146:465d6e40e79c
140 * ":import * as Name from 'filename'" 140 * ":import * as Name from 'filename'"
141 */ 141 */
142 void 142 void
143 ex_import(exarg_T *eap) 143 ex_import(exarg_T *eap)
144 { 144 {
145 char_u *cmd_end; 145 char_u *cmd_end;
146 evalarg_T evalarg;
146 147
147 if (!getline_equal(eap->getline, eap->cookie, getsourceline)) 148 if (!getline_equal(eap->getline, eap->cookie, getsourceline))
148 { 149 {
149 emsg(_("E1094: import can only be used in a script")); 150 emsg(_("E1094: import can only be used in a script"));
150 return; 151 return;
151 } 152 }
152 153 fill_evalarg_from_eap(&evalarg, eap, eap->skip);
153 cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid, NULL); 154
155 cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid,
156 &evalarg, NULL);
154 if (cmd_end != NULL) 157 if (cmd_end != NULL)
155 eap->nextcmd = check_nextcmd(cmd_end); 158 eap->nextcmd = check_nextcmd(cmd_end);
159 clear_evalarg(&evalarg, eap);
156 } 160 }
157 161
158 /* 162 /*
159 * Find an exported item in "sid" matching the name at "*argp". 163 * Find an exported item in "sid" matching the name at "*argp".
160 * When it is a variable return the index. 164 * When it is a variable return the index.
162 * When not found returns -1 and "*ufunc" is NULL. 166 * When not found returns -1 and "*ufunc" is NULL.
163 */ 167 */
164 int 168 int
165 find_exported( 169 find_exported(
166 int sid, 170 int sid,
167 char_u **argp, 171 char_u *name,
168 int *name_len,
169 ufunc_T **ufunc, 172 ufunc_T **ufunc,
170 type_T **type) 173 type_T **type)
171 { 174 {
172 char_u *name = *argp;
173 char_u *arg = *argp;
174 int cc;
175 int idx = -1; 175 int idx = -1;
176 svar_T *sv; 176 svar_T *sv;
177 scriptitem_T *script = SCRIPT_ITEM(sid); 177 scriptitem_T *script = SCRIPT_ITEM(sid);
178 178
179 // isolate one name
180 while (eval_isnamec(*arg))
181 ++arg;
182 *name_len = (int)(arg - name);
183
184 // find name in "script" 179 // find name in "script"
185 // TODO: also find script-local user function 180 // TODO: also find script-local user function
186 cc = *arg;
187 *arg = NUL;
188 idx = get_script_item_idx(sid, name, FALSE); 181 idx = get_script_item_idx(sid, name, FALSE);
189 if (idx >= 0) 182 if (idx >= 0)
190 { 183 {
191 sv = ((svar_T *)script->sn_var_vals.ga_data) + idx; 184 sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
192 if (!sv->sv_export) 185 if (!sv->sv_export)
193 { 186 {
194 semsg(_("E1049: Item not exported in script: %s"), name); 187 semsg(_("E1049: Item not exported in script: %s"), name);
195 *arg = cc;
196 return -1; 188 return -1;
197 } 189 }
198 *type = sv->sv_type; 190 *type = sv->sv_type;
199 *ufunc = NULL; 191 *ufunc = NULL;
200 } 192 }
208 funcname = buffer; 200 funcname = buffer;
209 else 201 else
210 { 202 {
211 funcname = alloc(STRLEN(name) + 10); 203 funcname = alloc(STRLEN(name) + 10);
212 if (funcname == NULL) 204 if (funcname == NULL)
213 {
214 *arg = cc;
215 return -1; 205 return -1;
216 }
217 } 206 }
218 funcname[0] = K_SPECIAL; 207 funcname[0] = K_SPECIAL;
219 funcname[1] = KS_EXTRA; 208 funcname[1] = KS_EXTRA;
220 funcname[2] = (int)KE_SNR; 209 funcname[2] = (int)KE_SNR;
221 sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); 210 sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name);
224 vim_free(funcname); 213 vim_free(funcname);
225 214
226 if (*ufunc == NULL) 215 if (*ufunc == NULL)
227 { 216 {
228 semsg(_("E1048: Item not found in script: %s"), name); 217 semsg(_("E1048: Item not found in script: %s"), name);
229 *arg = cc;
230 return -1; 218 return -1;
231 } 219 }
232 } 220 }
233 *arg = cc;
234 arg = skipwhite(arg);
235 *argp = arg;
236 221
237 return idx; 222 return idx;
238 } 223 }
239 224
240 /* 225 /*
241 * Handle an ":import" command and add the resulting imported_T to "gap", when 226 * Handle an ":import" command and add the resulting imported_T to "gap", when
242 * not NULL, or script "import_sid" sn_imports. 227 * not NULL, or script "import_sid" sn_imports.
243 * Returns a pointer to after the command or NULL in case of failure 228 * Returns a pointer to after the command or NULL in case of failure
244 */ 229 */
245 char_u * 230 char_u *
246 handle_import(char_u *arg_start, garray_T *gap, int import_sid, void *cctx) 231 handle_import(
232 char_u *arg_start,
233 garray_T *gap,
234 int import_sid,
235 evalarg_T *evalarg,
236 void *cctx)
247 { 237 {
248 char_u *arg = arg_start; 238 char_u *arg = arg_start;
249 char_u *cmd_end; 239 char_u *cmd_end = NULL;
250 char_u *as_ptr = NULL; 240 char_u *as_name = NULL;
251 char_u *from_ptr;
252 int as_len = 0;
253 int ret = FAIL; 241 int ret = FAIL;
254 typval_T tv; 242 typval_T tv;
255 int sid = -1; 243 int sid = -1;
256 int res; 244 int res;
257 245 garray_T names;
246 static char e_import_syntax[] = N_("E1047: syntax error in import");
247
248 ga_init2(&names, sizeof(char_u *), 10);
258 if (*arg == '{') 249 if (*arg == '{')
259 { 250 {
260 // skip over {item} list 251 // "import {item, item} from ..."
261 while (*arg != NUL && *arg != '}') 252 arg = skipwhite_and_linebreak(arg + 1, evalarg);
262 ++arg; 253 for (;;)
263 if (*arg == '}') 254 {
264 arg = skipwhite(arg + 1); 255 char_u *p = arg;
265 } 256 int had_comma = FALSE;
266 else 257
267 {
268 if (*arg == '*')
269 arg = skipwhite(arg + 1);
270 else if (eval_isnamec1(*arg))
271 {
272 while (eval_isnamec(*arg)) 258 while (eval_isnamec(*arg))
273 ++arg; 259 ++arg;
274 arg = skipwhite(arg); 260 if (p == arg)
275 } 261 break;
276 if (STRNCMP("as", arg, 2) == 0 && VIM_ISWHITE(arg[2])) 262 if (ga_grow(&names, 1) == FAIL)
277 { 263 goto erret;
278 // skip over "as Name " 264 ((char_u **)names.ga_data)[names.ga_len] =
265 vim_strnsave(p, arg - p);
266 ++names.ga_len;
267 if (*arg == ',')
268 {
269 had_comma = TRUE;
270 ++arg;
271 }
272 arg = skipwhite_and_linebreak(arg, evalarg);
273 if (*arg == '}')
274 {
275 arg = skipwhite_and_linebreak(arg + 1, evalarg);
276 break;
277 }
278 if (!had_comma)
279 {
280 emsg(_("E1046: Missing comma in import"));
281 goto erret;
282 }
283 }
284 if (names.ga_len == 0)
285 {
286 emsg(_(e_import_syntax));
287 goto erret;
288 }
289 }
290 else
291 {
292 // "import Name from ..."
293 // "import * as Name from ..."
294 // "import item [as Name] from ..."
295 arg = skipwhite_and_linebreak(arg, evalarg);
296 if (arg[0] == '*' && IS_WHITE_OR_NUL(arg[1]))
297 arg = skipwhite_and_linebreak(arg + 1, evalarg);
298 else if (eval_isnamec1(*arg))
299 {
300 char_u *p = arg;
301
302 while (eval_isnamec(*arg))
303 ++arg;
304 if (ga_grow(&names, 1) == FAIL)
305 goto erret;
306 ((char_u **)names.ga_data)[names.ga_len] =
307 vim_strnsave(p, arg - p);
308 ++names.ga_len;
309 arg = skipwhite_and_linebreak(arg, evalarg);
310 }
311 else
312 {
313 emsg(_(e_import_syntax));
314 goto erret;
315 }
316
317 if (STRNCMP("as", arg, 2) == 0 && IS_WHITE_OR_NUL(arg[2]))
318 {
319 char_u *p;
320
321 // skip over "as Name "; no line break allowed after "as"
279 arg = skipwhite(arg + 2); 322 arg = skipwhite(arg + 2);
280 as_ptr = arg; 323 p = arg;
281 if (eval_isnamec1(*arg)) 324 if (eval_isnamec1(*arg))
282 while (eval_isnamec(*arg)) 325 while (eval_isnamec(*arg))
283 ++arg; 326 ++arg;
284 as_len = (int)(arg - as_ptr); 327 if (check_defined(p, (int)(arg - p), cctx) == FAIL)
285 arg = skipwhite(arg); 328 goto erret;
286 if (check_defined(as_ptr, as_len, cctx) == FAIL) 329 as_name = vim_strnsave(p, arg - p);
287 return NULL; 330 arg = skipwhite_and_linebreak(arg, evalarg);
288 } 331 }
289 else if (*arg_start == '*') 332 else if (*arg_start == '*')
290 { 333 {
291 emsg(_("E1045: Missing \"as\" after *")); 334 emsg(_("E1045: Missing \"as\" after *"));
292 return NULL; 335 goto erret;
293 } 336 }
294 } 337 }
295 if (STRNCMP("from", arg, 4) != 0 || !VIM_ISWHITE(arg[4])) 338
339 if (STRNCMP("from", arg, 4) != 0 || !IS_WHITE_OR_NUL(arg[4]))
296 { 340 {
297 emsg(_("E1070: Missing \"from\"")); 341 emsg(_("E1070: Missing \"from\""));
298 return NULL; 342 goto erret;
299 } 343 }
300 from_ptr = arg; 344
301 arg = skipwhite(arg + 4); 345 arg = skipwhite_and_linebreak_keep_string(arg + 4, evalarg);
302 tv.v_type = VAR_UNKNOWN; 346 tv.v_type = VAR_UNKNOWN;
303 // TODO: should we accept any expression? 347 // TODO: should we accept any expression?
304 if (*arg == '\'') 348 if (*arg == '\'')
305 ret = eval_lit_string(&arg, &tv, TRUE); 349 ret = eval_lit_string(&arg, &tv, TRUE);
306 else if (*arg == '"') 350 else if (*arg == '"')
307 ret = eval_string(&arg, &tv, TRUE); 351 ret = eval_string(&arg, &tv, TRUE);
308 if (ret == FAIL || tv.vval.v_string == NULL || *tv.vval.v_string == NUL) 352 if (ret == FAIL || tv.vval.v_string == NULL || *tv.vval.v_string == NUL)
309 { 353 {
310 emsg(_("E1071: Invalid string after \"from\"")); 354 emsg(_("E1071: Invalid string after \"from\""));
311 return NULL; 355 goto erret;
312 } 356 }
313 cmd_end = arg; 357 cmd_end = arg;
314 358
315 // find script tv.vval.v_string 359 /*
360 * find script file
361 */
316 if (*tv.vval.v_string == '.') 362 if (*tv.vval.v_string == '.')
317 { 363 {
318 size_t len; 364 size_t len;
319 scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); 365 scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
320 char_u *tail = gettail(si->sn_name); 366 char_u *tail = gettail(si->sn_name);
324 len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2; 370 len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
325 from_name = alloc((int)len); 371 from_name = alloc((int)len);
326 if (from_name == NULL) 372 if (from_name == NULL)
327 { 373 {
328 clear_tv(&tv); 374 clear_tv(&tv);
329 return NULL; 375 goto erret;
330 } 376 }
331 vim_strncpy(from_name, si->sn_name, tail - si->sn_name); 377 vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
332 add_pathsep(from_name); 378 add_pathsep(from_name);
333 STRCAT(from_name, tv.vval.v_string); 379 STRCAT(from_name, tv.vval.v_string);
334 simplify_filename(from_name); 380 simplify_filename(from_name);
349 // Find file in "import" subdirs in 'runtimepath'. 395 // Find file in "import" subdirs in 'runtimepath'.
350 from_name = alloc((int)len); 396 from_name = alloc((int)len);
351 if (from_name == NULL) 397 if (from_name == NULL)
352 { 398 {
353 clear_tv(&tv); 399 clear_tv(&tv);
354 return NULL; 400 goto erret;
355 } 401 }
356 vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string); 402 vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string);
357 res = source_in_path(p_rtp, from_name, DIP_NOAFTER, &sid); 403 res = source_in_path(p_rtp, from_name, DIP_NOAFTER, &sid);
358 vim_free(from_name); 404 vim_free(from_name);
359 } 405 }
360 406
361 if (res == FAIL || sid <= 0) 407 if (res == FAIL || sid <= 0)
362 { 408 {
363 semsg(_("E1053: Could not import \"%s\""), tv.vval.v_string); 409 semsg(_("E1053: Could not import \"%s\""), tv.vval.v_string);
364 clear_tv(&tv); 410 clear_tv(&tv);
365 return NULL; 411 goto erret;
366 } 412 }
367 clear_tv(&tv); 413 clear_tv(&tv);
368 414
369 if (*arg_start == '*') 415 if (*arg_start == '*')
370 { 416 {
371 imported_T *imported = new_imported(gap != NULL ? gap 417 imported_T *imported = new_imported(gap != NULL ? gap
372 : &SCRIPT_ITEM(import_sid)->sn_imports); 418 : &SCRIPT_ITEM(import_sid)->sn_imports);
373 419
374 if (imported == NULL) 420 if (imported == NULL)
375 return NULL; 421 goto erret;
376 imported->imp_name = vim_strnsave(as_ptr, as_len); 422 imported->imp_name = as_name;
423 as_name = NULL;
377 imported->imp_sid = sid; 424 imported->imp_sid = sid;
378 imported->imp_all = TRUE; 425 imported->imp_all = TRUE;
379 } 426 }
380 else 427 else
381 { 428 {
429 int i;
430
382 arg = arg_start; 431 arg = arg_start;
383 if (*arg == '{') 432 if (*arg == '{')
384 arg = skipwhite(arg + 1); 433 arg = skipwhite(arg + 1);
385 for (;;) 434 for (i = 0; i < names.ga_len; ++i)
386 { 435 {
387 char_u *name = arg; 436 char_u *name = ((char_u **)names.ga_data)[i];
388 int name_len;
389 int idx; 437 int idx;
390 imported_T *imported; 438 imported_T *imported;
391 ufunc_T *ufunc = NULL; 439 ufunc_T *ufunc = NULL;
392 type_T *type; 440 type_T *type;
393 441
394 idx = find_exported(sid, &arg, &name_len, &ufunc, &type); 442 idx = find_exported(sid, name, &ufunc, &type);
395 443
396 if (idx < 0 && ufunc == NULL) 444 if (idx < 0 && ufunc == NULL)
397 return NULL; 445 goto erret;
398 446
399 if (check_defined(name, name_len, cctx) == FAIL) 447 if (check_defined(name, STRLEN(name), cctx) == FAIL)
400 return NULL; 448 goto erret;
401 449
402 imported = new_imported(gap != NULL ? gap 450 imported = new_imported(gap != NULL ? gap
403 : &SCRIPT_ITEM(import_sid)->sn_imports); 451 : &SCRIPT_ITEM(import_sid)->sn_imports);
404 if (imported == NULL) 452 if (imported == NULL)
405 return NULL; 453 goto erret;
406 454
407 // TODO: check for "as" following 455 // TODO: check for "as" following
408 // imported->imp_name = vim_strnsave(as_ptr, as_len); 456 // imported->imp_name = vim_strsave(as_name);
409 imported->imp_name = vim_strnsave(name, name_len); 457 imported->imp_name = name;
458 ((char_u **)names.ga_data)[i] = NULL;
410 imported->imp_sid = sid; 459 imported->imp_sid = sid;
411 if (idx >= 0) 460 if (idx >= 0)
412 { 461 {
413 imported->imp_type = type; 462 imported->imp_type = type;
414 imported->imp_var_vals_idx = idx; 463 imported->imp_var_vals_idx = idx;
415 } 464 }
416 else 465 else
417 imported->imp_funcname = ufunc->uf_name; 466 imported->imp_funcname = ufunc->uf_name;
418 467 }
419 arg = skipwhite(arg); 468 }
420 if (*arg_start != '{') 469 erret:
421 break; 470 ga_clear_strings(&names);
422 if (*arg == '}') 471 vim_free(as_name);
423 {
424 arg = skipwhite(arg + 1);
425 break;
426 }
427
428 if (*arg != ',')
429 {
430 emsg(_("E1046: Missing comma in import"));
431 return NULL;
432 }
433 arg = skipwhite(arg + 1);
434 }
435 if (arg != from_ptr)
436 {
437 // cannot happen, just in case the above has a flaw
438 emsg(_("E1047: syntax error in import"));
439 return NULL;
440 }
441 }
442 return cmd_end; 472 return cmd_end;
443 } 473 }
444 474
445 /* 475 /*
446 * Declare a script-local variable without init: "let var: type". 476 * Declare a script-local variable without init: "let var: type".