18a7d6542SBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet: 28a7d6542SBram Moolenaar * 38a7d6542SBram Moolenaar * VIM - Vi IMproved by Bram Moolenaar 48a7d6542SBram Moolenaar * 58a7d6542SBram Moolenaar * Do ":help uganda" in Vim to read copying and usage conditions. 68a7d6542SBram Moolenaar * Do ":help credits" in Vim to see a list of people who contributed. 78a7d6542SBram Moolenaar * See README.txt for an overview of the Vim source code. 88a7d6542SBram Moolenaar */ 98a7d6542SBram Moolenaar 108a7d6542SBram Moolenaar /* 118a7d6542SBram Moolenaar * vim9script.c: :vim9script, :import, :export and friends 128a7d6542SBram Moolenaar */ 138a7d6542SBram Moolenaar 148a7d6542SBram Moolenaar #include "vim.h" 158a7d6542SBram Moolenaar 168a7d6542SBram Moolenaar #if defined(FEAT_EVAL) || defined(PROTO) 178a7d6542SBram Moolenaar 188a7d6542SBram Moolenaar #include "vim9.h" 198a7d6542SBram Moolenaar 208a7d6542SBram Moolenaar static char e_needs_vim9[] = N_("E1042: import/export can only be used in vim9script"); 218a7d6542SBram Moolenaar 228a7d6542SBram Moolenaar int 238a7d6542SBram Moolenaar in_vim9script(void) 248a7d6542SBram Moolenaar { 258a7d6542SBram Moolenaar // TODO: go up the stack? 268a7d6542SBram Moolenaar return current_sctx.sc_version == SCRIPT_VERSION_VIM9; 278a7d6542SBram Moolenaar } 288a7d6542SBram Moolenaar 298a7d6542SBram Moolenaar /* 308a7d6542SBram Moolenaar * ":vim9script". 318a7d6542SBram Moolenaar */ 328a7d6542SBram Moolenaar void 338a7d6542SBram Moolenaar ex_vim9script(exarg_T *eap) 348a7d6542SBram Moolenaar { 3521b9e977SBram Moolenaar scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); 368a7d6542SBram Moolenaar 378a7d6542SBram Moolenaar if (!getline_equal(eap->getline, eap->cookie, getsourceline)) 388a7d6542SBram Moolenaar { 398a7d6542SBram Moolenaar emsg(_("E1038: vim9script can only be used in a script")); 408a7d6542SBram Moolenaar return; 418a7d6542SBram Moolenaar } 428a7d6542SBram Moolenaar if (si->sn_had_command) 438a7d6542SBram Moolenaar { 448a7d6542SBram Moolenaar emsg(_("E1039: vim9script must be the first command in a script")); 458a7d6542SBram Moolenaar return; 468a7d6542SBram Moolenaar } 478a7d6542SBram Moolenaar current_sctx.sc_version = SCRIPT_VERSION_VIM9; 488a7d6542SBram Moolenaar si->sn_version = SCRIPT_VERSION_VIM9; 498a7d6542SBram Moolenaar si->sn_had_command = TRUE; 508a7d6542SBram Moolenaar 518a7d6542SBram Moolenaar if (STRCMP(p_cpo, CPO_VIM) != 0) 528a7d6542SBram Moolenaar { 538a7d6542SBram Moolenaar si->sn_save_cpo = p_cpo; 548a7d6542SBram Moolenaar p_cpo = vim_strsave((char_u *)CPO_VIM); 558a7d6542SBram Moolenaar } 568a7d6542SBram Moolenaar } 578a7d6542SBram Moolenaar 588a7d6542SBram Moolenaar /* 598a7d6542SBram Moolenaar * ":export let Name: type" 608a7d6542SBram Moolenaar * ":export const Name: type" 618a7d6542SBram Moolenaar * ":export def Name(..." 628a7d6542SBram Moolenaar * ":export class Name ..." 638a7d6542SBram Moolenaar * 648a7d6542SBram Moolenaar * ":export {Name, ...}" 658a7d6542SBram Moolenaar */ 668a7d6542SBram Moolenaar void 678a7d6542SBram Moolenaar ex_export(exarg_T *eap UNUSED) 688a7d6542SBram Moolenaar { 698a7d6542SBram Moolenaar if (current_sctx.sc_version != SCRIPT_VERSION_VIM9) 708a7d6542SBram Moolenaar { 718a7d6542SBram Moolenaar emsg(_(e_needs_vim9)); 728a7d6542SBram Moolenaar return; 738a7d6542SBram Moolenaar } 748a7d6542SBram Moolenaar 758a7d6542SBram Moolenaar eap->cmd = eap->arg; 768a7d6542SBram Moolenaar (void)find_ex_command(eap, NULL, lookup_scriptvar, NULL); 778a7d6542SBram Moolenaar switch (eap->cmdidx) 788a7d6542SBram Moolenaar { 798a7d6542SBram Moolenaar case CMD_let: 808a7d6542SBram Moolenaar case CMD_const: 818a7d6542SBram Moolenaar case CMD_def: 828a7d6542SBram Moolenaar // case CMD_class: 838a7d6542SBram Moolenaar is_export = TRUE; 848a7d6542SBram Moolenaar do_cmdline(eap->cmd, eap->getline, eap->cookie, 858a7d6542SBram Moolenaar DOCMD_VERBOSE + DOCMD_NOWAIT); 868a7d6542SBram Moolenaar 878a7d6542SBram Moolenaar // The command will reset "is_export" when exporting an item. 888a7d6542SBram Moolenaar if (is_export) 898a7d6542SBram Moolenaar { 908a7d6542SBram Moolenaar emsg(_("E1044: export with invalid argument")); 918a7d6542SBram Moolenaar is_export = FALSE; 928a7d6542SBram Moolenaar } 938a7d6542SBram Moolenaar break; 948a7d6542SBram Moolenaar default: 958a7d6542SBram Moolenaar emsg(_("E1043: Invalid command after :export")); 968a7d6542SBram Moolenaar break; 978a7d6542SBram Moolenaar } 988a7d6542SBram Moolenaar } 998a7d6542SBram Moolenaar 1008a7d6542SBram Moolenaar /* 1018a7d6542SBram Moolenaar * Add a new imported item entry to the current script. 1028a7d6542SBram Moolenaar */ 1038a7d6542SBram Moolenaar static imported_T * 1048a7d6542SBram Moolenaar new_imported(garray_T *gap) 1058a7d6542SBram Moolenaar { 1068a7d6542SBram Moolenaar if (ga_grow(gap, 1) == OK) 1078a7d6542SBram Moolenaar return ((imported_T *)gap->ga_data + gap->ga_len++); 1088a7d6542SBram Moolenaar return NULL; 1098a7d6542SBram Moolenaar } 1108a7d6542SBram Moolenaar 1118a7d6542SBram Moolenaar /* 1128a7d6542SBram Moolenaar * Free all imported items in script "sid". 1138a7d6542SBram Moolenaar */ 1148a7d6542SBram Moolenaar void 1158a7d6542SBram Moolenaar free_imports(int sid) 1168a7d6542SBram Moolenaar { 11721b9e977SBram Moolenaar scriptitem_T *si = SCRIPT_ITEM(sid); 1188a7d6542SBram Moolenaar int idx; 1198a7d6542SBram Moolenaar 1208a7d6542SBram Moolenaar for (idx = 0; idx < si->sn_imports.ga_len; ++idx) 1218a7d6542SBram Moolenaar { 1228a7d6542SBram Moolenaar imported_T *imp = ((imported_T *)si->sn_imports.ga_data + idx); 1238a7d6542SBram Moolenaar 1248a7d6542SBram Moolenaar vim_free(imp->imp_name); 1258a7d6542SBram Moolenaar } 1268a7d6542SBram Moolenaar ga_clear(&si->sn_imports); 1278a7d6542SBram Moolenaar } 1288a7d6542SBram Moolenaar 1298a7d6542SBram Moolenaar /* 1308a7d6542SBram Moolenaar * ":import Item from 'filename'" 1318a7d6542SBram Moolenaar * ":import Item as Alias from 'filename'" 1328a7d6542SBram Moolenaar * ":import {Item} from 'filename'". 1338a7d6542SBram Moolenaar * ":import {Item as Alias} from 'filename'" 1348a7d6542SBram Moolenaar * ":import {Item, Item} from 'filename'" 1358a7d6542SBram Moolenaar * ":import {Item, Item as Alias} from 'filename'" 1368a7d6542SBram Moolenaar * 1378a7d6542SBram Moolenaar * ":import * as Name from 'filename'" 1388a7d6542SBram Moolenaar */ 1398a7d6542SBram Moolenaar void 1408a7d6542SBram Moolenaar ex_import(exarg_T *eap) 1418a7d6542SBram Moolenaar { 1428a7d6542SBram Moolenaar if (current_sctx.sc_version != SCRIPT_VERSION_VIM9) 1438a7d6542SBram Moolenaar emsg(_(e_needs_vim9)); 1448a7d6542SBram Moolenaar else 1458a7d6542SBram Moolenaar { 1468a7d6542SBram Moolenaar char_u *cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid); 1478a7d6542SBram Moolenaar 1488a7d6542SBram Moolenaar if (cmd_end != NULL) 1498a7d6542SBram Moolenaar eap->nextcmd = check_nextcmd(cmd_end); 1508a7d6542SBram Moolenaar } 1518a7d6542SBram Moolenaar } 1528a7d6542SBram Moolenaar 1538a7d6542SBram Moolenaar /* 154f2d5c240SBram Moolenaar * Find an exported item in "sid" matching the name at "*argp". 155f2d5c240SBram Moolenaar * When it is a variable return the index. 156f2d5c240SBram Moolenaar * When it is a user function return "*ufunc". 157f2d5c240SBram Moolenaar * When not found returns -1 and "*ufunc" is NULL. 158f2d5c240SBram Moolenaar */ 159f2d5c240SBram Moolenaar int 160f2d5c240SBram Moolenaar find_exported( 161f2d5c240SBram Moolenaar int sid, 162f2d5c240SBram Moolenaar char_u **argp, 163f2d5c240SBram Moolenaar int *name_len, 164f2d5c240SBram Moolenaar ufunc_T **ufunc, 165f2d5c240SBram Moolenaar type_T **type) 166f2d5c240SBram Moolenaar { 167f2d5c240SBram Moolenaar char_u *name = *argp; 168f2d5c240SBram Moolenaar char_u *arg = *argp; 169f2d5c240SBram Moolenaar int cc; 170f2d5c240SBram Moolenaar int idx = -1; 171f2d5c240SBram Moolenaar svar_T *sv; 172f2d5c240SBram Moolenaar scriptitem_T *script = SCRIPT_ITEM(sid); 173f2d5c240SBram Moolenaar 174f2d5c240SBram Moolenaar // isolate one name 175*fa29c8abSBram Moolenaar while (eval_isnamec(*arg)) 176f2d5c240SBram Moolenaar ++arg; 177f2d5c240SBram Moolenaar *name_len = (int)(arg - name); 178f2d5c240SBram Moolenaar 179f2d5c240SBram Moolenaar // find name in "script" 180f2d5c240SBram Moolenaar // TODO: also find script-local user function 181f2d5c240SBram Moolenaar cc = *arg; 182f2d5c240SBram Moolenaar *arg = NUL; 183f2d5c240SBram Moolenaar idx = get_script_item_idx(sid, name, FALSE); 184f2d5c240SBram Moolenaar if (idx >= 0) 185f2d5c240SBram Moolenaar { 186f2d5c240SBram Moolenaar sv = ((svar_T *)script->sn_var_vals.ga_data) + idx; 187f2d5c240SBram Moolenaar if (!sv->sv_export) 188f2d5c240SBram Moolenaar { 189f2d5c240SBram Moolenaar semsg(_("E1049: Item not exported in script: %s"), name); 190f2d5c240SBram Moolenaar *arg = cc; 191f2d5c240SBram Moolenaar return -1; 192f2d5c240SBram Moolenaar } 193f2d5c240SBram Moolenaar *type = sv->sv_type; 194f2d5c240SBram Moolenaar *ufunc = NULL; 195f2d5c240SBram Moolenaar } 196f2d5c240SBram Moolenaar else 197f2d5c240SBram Moolenaar { 198f2d5c240SBram Moolenaar char_u buffer[200]; 199f2d5c240SBram Moolenaar char_u *funcname; 200f2d5c240SBram Moolenaar 201f2d5c240SBram Moolenaar // it could be a user function. 202f2d5c240SBram Moolenaar if (STRLEN(name) < sizeof(buffer) - 10) 203f2d5c240SBram Moolenaar funcname = buffer; 204f2d5c240SBram Moolenaar else 205f2d5c240SBram Moolenaar { 206f2d5c240SBram Moolenaar funcname = alloc(STRLEN(name) + 10); 207f2d5c240SBram Moolenaar if (funcname == NULL) 208f2d5c240SBram Moolenaar { 209f2d5c240SBram Moolenaar *arg = cc; 210f2d5c240SBram Moolenaar return -1; 211f2d5c240SBram Moolenaar } 212f2d5c240SBram Moolenaar } 213f2d5c240SBram Moolenaar funcname[0] = K_SPECIAL; 214f2d5c240SBram Moolenaar funcname[1] = KS_EXTRA; 215f2d5c240SBram Moolenaar funcname[2] = (int)KE_SNR; 216f2d5c240SBram Moolenaar sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); 217f2d5c240SBram Moolenaar *ufunc = find_func(funcname, NULL); 218f2d5c240SBram Moolenaar if (funcname != buffer) 219f2d5c240SBram Moolenaar vim_free(funcname); 220f2d5c240SBram Moolenaar 221f2d5c240SBram Moolenaar if (*ufunc == NULL) 222f2d5c240SBram Moolenaar { 223f2d5c240SBram Moolenaar semsg(_("E1048: Item not found in script: %s"), name); 224f2d5c240SBram Moolenaar *arg = cc; 225f2d5c240SBram Moolenaar return -1; 226f2d5c240SBram Moolenaar } 227f2d5c240SBram Moolenaar } 228f2d5c240SBram Moolenaar *arg = cc; 229f2d5c240SBram Moolenaar arg = skipwhite(arg); 230f2d5c240SBram Moolenaar *argp = arg; 231f2d5c240SBram Moolenaar 232f2d5c240SBram Moolenaar return idx; 233f2d5c240SBram Moolenaar } 234f2d5c240SBram Moolenaar 235f2d5c240SBram Moolenaar /* 2368a7d6542SBram Moolenaar * Handle an ":import" command and add the resulting imported_T to "gap", when 2378a7d6542SBram Moolenaar * not NULL, or script "import_sid" sn_imports. 2388a7d6542SBram Moolenaar * Returns a pointer to after the command or NULL in case of failure 2398a7d6542SBram Moolenaar */ 2408a7d6542SBram Moolenaar char_u * 2418a7d6542SBram Moolenaar handle_import(char_u *arg_start, garray_T *gap, int import_sid) 2428a7d6542SBram Moolenaar { 2438a7d6542SBram Moolenaar char_u *arg = arg_start; 2448a7d6542SBram Moolenaar char_u *cmd_end; 2458a7d6542SBram Moolenaar char_u *as_ptr = NULL; 2468a7d6542SBram Moolenaar char_u *from_ptr; 2478a7d6542SBram Moolenaar int as_len = 0; 2488a7d6542SBram Moolenaar int ret = FAIL; 2498a7d6542SBram Moolenaar typval_T tv; 2508a7d6542SBram Moolenaar int sid = -1; 2518a7d6542SBram Moolenaar int res; 2528a7d6542SBram Moolenaar 2538a7d6542SBram Moolenaar if (*arg == '{') 2548a7d6542SBram Moolenaar { 2558a7d6542SBram Moolenaar // skip over {item} list 2568a7d6542SBram Moolenaar while (*arg != NUL && *arg != '}') 2578a7d6542SBram Moolenaar ++arg; 2588a7d6542SBram Moolenaar if (*arg == '}') 2598a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 2608a7d6542SBram Moolenaar } 2618a7d6542SBram Moolenaar else 2628a7d6542SBram Moolenaar { 2638a7d6542SBram Moolenaar if (*arg == '*') 2648a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 265*fa29c8abSBram Moolenaar else if (eval_isnamec1(*arg)) 2668a7d6542SBram Moolenaar { 267*fa29c8abSBram Moolenaar while (eval_isnamec(*arg)) 2688a7d6542SBram Moolenaar ++arg; 2698a7d6542SBram Moolenaar arg = skipwhite(arg); 2708a7d6542SBram Moolenaar } 2718a7d6542SBram Moolenaar if (STRNCMP("as", arg, 2) == 0 && VIM_ISWHITE(arg[2])) 2728a7d6542SBram Moolenaar { 2738a7d6542SBram Moolenaar // skip over "as Name " 2748a7d6542SBram Moolenaar arg = skipwhite(arg + 2); 2758a7d6542SBram Moolenaar as_ptr = arg; 276*fa29c8abSBram Moolenaar if (eval_isnamec1(*arg)) 277*fa29c8abSBram Moolenaar while (eval_isnamec(*arg)) 2788a7d6542SBram Moolenaar ++arg; 2798a7d6542SBram Moolenaar as_len = (int)(arg - as_ptr); 2808a7d6542SBram Moolenaar arg = skipwhite(arg); 2818a7d6542SBram Moolenaar } 2828a7d6542SBram Moolenaar else if (*arg_start == '*') 2838a7d6542SBram Moolenaar { 2848a7d6542SBram Moolenaar emsg(_("E1045: Missing \"as\" after *")); 2858a7d6542SBram Moolenaar return NULL; 2868a7d6542SBram Moolenaar } 2878a7d6542SBram Moolenaar } 2888a7d6542SBram Moolenaar if (STRNCMP("from", arg, 4) != 0 || !VIM_ISWHITE(arg[4])) 2898a7d6542SBram Moolenaar { 290*fa29c8abSBram Moolenaar emsg(_("E1070: Missing \"from\"")); 2918a7d6542SBram Moolenaar return NULL; 2928a7d6542SBram Moolenaar } 2938a7d6542SBram Moolenaar from_ptr = arg; 2948a7d6542SBram Moolenaar arg = skipwhite(arg + 4); 2958a7d6542SBram Moolenaar tv.v_type = VAR_UNKNOWN; 2968a7d6542SBram Moolenaar // TODO: should we accept any expression? 2978a7d6542SBram Moolenaar if (*arg == '\'') 2988a7d6542SBram Moolenaar ret = get_lit_string_tv(&arg, &tv, TRUE); 2998a7d6542SBram Moolenaar else if (*arg == '"') 3008a7d6542SBram Moolenaar ret = get_string_tv(&arg, &tv, TRUE); 3018a7d6542SBram Moolenaar if (ret == FAIL || tv.vval.v_string == NULL || *tv.vval.v_string == NUL) 3028a7d6542SBram Moolenaar { 303*fa29c8abSBram Moolenaar emsg(_("E1071: Invalid string after \"from\"")); 3048a7d6542SBram Moolenaar return NULL; 3058a7d6542SBram Moolenaar } 3068a7d6542SBram Moolenaar cmd_end = arg; 3078a7d6542SBram Moolenaar 3088a7d6542SBram Moolenaar // find script tv.vval.v_string 3098a7d6542SBram Moolenaar if (*tv.vval.v_string == '.') 3108a7d6542SBram Moolenaar { 3118a7d6542SBram Moolenaar size_t len; 31221b9e977SBram Moolenaar scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); 3138a7d6542SBram Moolenaar char_u *tail = gettail(si->sn_name); 3148a7d6542SBram Moolenaar char_u *from_name; 3158a7d6542SBram Moolenaar 3168a7d6542SBram Moolenaar // Relative to current script: "./name.vim", "../../name.vim". 3178a7d6542SBram Moolenaar len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2; 3188a7d6542SBram Moolenaar from_name = alloc((int)len); 3198a7d6542SBram Moolenaar if (from_name == NULL) 3208a7d6542SBram Moolenaar { 3218a7d6542SBram Moolenaar clear_tv(&tv); 3228a7d6542SBram Moolenaar return NULL; 3238a7d6542SBram Moolenaar } 3248a7d6542SBram Moolenaar vim_strncpy(from_name, si->sn_name, tail - si->sn_name); 3258a7d6542SBram Moolenaar add_pathsep(from_name); 3268a7d6542SBram Moolenaar STRCAT(from_name, tv.vval.v_string); 3278a7d6542SBram Moolenaar simplify_filename(from_name); 3288a7d6542SBram Moolenaar 3298a7d6542SBram Moolenaar res = do_source(from_name, FALSE, DOSO_NONE, &sid); 3308a7d6542SBram Moolenaar vim_free(from_name); 3318a7d6542SBram Moolenaar } 3328a7d6542SBram Moolenaar else if (mch_isFullName(tv.vval.v_string)) 3338a7d6542SBram Moolenaar { 3348a7d6542SBram Moolenaar // Absolute path: "/tmp/name.vim" 3358a7d6542SBram Moolenaar res = do_source(tv.vval.v_string, FALSE, DOSO_NONE, &sid); 3368a7d6542SBram Moolenaar } 3378a7d6542SBram Moolenaar else 3388a7d6542SBram Moolenaar { 3398a7d6542SBram Moolenaar size_t len = 7 + STRLEN(tv.vval.v_string) + 1; 3408a7d6542SBram Moolenaar char_u *from_name; 3418a7d6542SBram Moolenaar 3428a7d6542SBram Moolenaar // Find file in "import" subdirs in 'runtimepath'. 3438a7d6542SBram Moolenaar from_name = alloc((int)len); 3448a7d6542SBram Moolenaar if (from_name == NULL) 3458a7d6542SBram Moolenaar { 3468a7d6542SBram Moolenaar clear_tv(&tv); 3478a7d6542SBram Moolenaar return NULL; 3488a7d6542SBram Moolenaar } 3498a7d6542SBram Moolenaar vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string); 3508a7d6542SBram Moolenaar res = source_in_path(p_rtp, from_name, DIP_NOAFTER, &sid); 3518a7d6542SBram Moolenaar vim_free(from_name); 3528a7d6542SBram Moolenaar } 3538a7d6542SBram Moolenaar 3548a7d6542SBram Moolenaar if (res == FAIL || sid <= 0) 3558a7d6542SBram Moolenaar { 3568a7d6542SBram Moolenaar semsg(_("E1053: Could not import \"%s\""), tv.vval.v_string); 3578a7d6542SBram Moolenaar clear_tv(&tv); 3588a7d6542SBram Moolenaar return NULL; 3598a7d6542SBram Moolenaar } 3608a7d6542SBram Moolenaar clear_tv(&tv); 3618a7d6542SBram Moolenaar 3628a7d6542SBram Moolenaar if (*arg_start == '*') 3638a7d6542SBram Moolenaar { 3648a7d6542SBram Moolenaar imported_T *imported = new_imported(gap != NULL ? gap 36521b9e977SBram Moolenaar : &SCRIPT_ITEM(import_sid)->sn_imports); 3668a7d6542SBram Moolenaar 3678a7d6542SBram Moolenaar if (imported == NULL) 3688a7d6542SBram Moolenaar return NULL; 3698a7d6542SBram Moolenaar imported->imp_name = vim_strnsave(as_ptr, as_len); 3708a7d6542SBram Moolenaar imported->imp_sid = sid; 3718a7d6542SBram Moolenaar imported->imp_all = TRUE; 3728a7d6542SBram Moolenaar } 3738a7d6542SBram Moolenaar else 3748a7d6542SBram Moolenaar { 3758a7d6542SBram Moolenaar arg = arg_start; 3768a7d6542SBram Moolenaar if (*arg == '{') 3778a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 3788a7d6542SBram Moolenaar for (;;) 3798a7d6542SBram Moolenaar { 3808a7d6542SBram Moolenaar char_u *name = arg; 3818a7d6542SBram Moolenaar int name_len; 3828a7d6542SBram Moolenaar int idx; 3838a7d6542SBram Moolenaar imported_T *imported; 384f2d5c240SBram Moolenaar ufunc_T *ufunc = NULL; 385f2d5c240SBram Moolenaar type_T *type; 3868a7d6542SBram Moolenaar 387f2d5c240SBram Moolenaar idx = find_exported(sid, &arg, &name_len, &ufunc, &type); 3888a7d6542SBram Moolenaar 389f2d5c240SBram Moolenaar if (idx < 0 && ufunc == NULL) 3908a7d6542SBram Moolenaar return NULL; 3918a7d6542SBram Moolenaar 3928a7d6542SBram Moolenaar imported = new_imported(gap != NULL ? gap 39321b9e977SBram Moolenaar : &SCRIPT_ITEM(import_sid)->sn_imports); 3948a7d6542SBram Moolenaar if (imported == NULL) 3958a7d6542SBram Moolenaar return NULL; 3968a7d6542SBram Moolenaar 3978a7d6542SBram Moolenaar // TODO: check for "as" following 3988a7d6542SBram Moolenaar // imported->imp_name = vim_strnsave(as_ptr, as_len); 3998a7d6542SBram Moolenaar imported->imp_name = vim_strnsave(name, name_len); 4008a7d6542SBram Moolenaar imported->imp_sid = sid; 4018a7d6542SBram Moolenaar if (idx >= 0) 4028a7d6542SBram Moolenaar { 403f2d5c240SBram Moolenaar imported->imp_type = type; 4048a7d6542SBram Moolenaar imported->imp_var_vals_idx = idx; 4058a7d6542SBram Moolenaar } 4068a7d6542SBram Moolenaar else 4078a7d6542SBram Moolenaar imported->imp_funcname = ufunc->uf_name; 4088a7d6542SBram Moolenaar 4098a7d6542SBram Moolenaar arg = skipwhite(arg); 4108a7d6542SBram Moolenaar if (*arg_start != '{') 4118a7d6542SBram Moolenaar break; 4128a7d6542SBram Moolenaar if (*arg == '}') 4138a7d6542SBram Moolenaar { 4148a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 4158a7d6542SBram Moolenaar break; 4168a7d6542SBram Moolenaar } 4178a7d6542SBram Moolenaar 4188a7d6542SBram Moolenaar if (*arg != ',') 4198a7d6542SBram Moolenaar { 4208a7d6542SBram Moolenaar emsg(_("E1046: Missing comma in import")); 4218a7d6542SBram Moolenaar return NULL; 4228a7d6542SBram Moolenaar } 4238a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 4248a7d6542SBram Moolenaar } 4258a7d6542SBram Moolenaar if (arg != from_ptr) 4268a7d6542SBram Moolenaar { 427*fa29c8abSBram Moolenaar // cannot happen, just in case the above has a flaw 4288a7d6542SBram Moolenaar emsg(_("E1047: syntax error in import")); 4298a7d6542SBram Moolenaar return NULL; 4308a7d6542SBram Moolenaar } 4318a7d6542SBram Moolenaar } 4328a7d6542SBram Moolenaar return cmd_end; 4338a7d6542SBram Moolenaar } 4348a7d6542SBram Moolenaar 4358a7d6542SBram Moolenaar #endif // FEAT_EVAL 436