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 20*9721fb4eSBram Moolenaar static char e_needs_vim9[] = N_("E1042: 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 } 56227a69deSBram 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 6709689a02SBram Moolenaar ex_export(exarg_T *eap) 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 { 12220431c9dSBram 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); 12720431c9dSBram Moolenaar ga_clear(&si->sn_var_vals); 12820431c9dSBram Moolenaar ga_clear(&si->sn_type_list); 1298a7d6542SBram Moolenaar } 1308a7d6542SBram Moolenaar 1318a7d6542SBram Moolenaar /* 1328a7d6542SBram Moolenaar * ":import Item from 'filename'" 1338a7d6542SBram Moolenaar * ":import Item as Alias from 'filename'" 1348a7d6542SBram Moolenaar * ":import {Item} from 'filename'". 1358a7d6542SBram Moolenaar * ":import {Item as Alias} from 'filename'" 1368a7d6542SBram Moolenaar * ":import {Item, Item} from 'filename'" 1378a7d6542SBram Moolenaar * ":import {Item, Item as Alias} from 'filename'" 1388a7d6542SBram Moolenaar * 1398a7d6542SBram Moolenaar * ":import * as Name from 'filename'" 1408a7d6542SBram Moolenaar */ 1418a7d6542SBram Moolenaar void 1428a7d6542SBram Moolenaar ex_import(exarg_T *eap) 1438a7d6542SBram Moolenaar { 144*9721fb4eSBram Moolenaar char_u *cmd_end = handle_import(eap->arg, NULL, current_sctx.sc_sid, NULL); 1458a7d6542SBram Moolenaar 1468a7d6542SBram Moolenaar if (cmd_end != NULL) 1478a7d6542SBram Moolenaar eap->nextcmd = check_nextcmd(cmd_end); 1488a7d6542SBram Moolenaar } 1498a7d6542SBram Moolenaar 1508a7d6542SBram Moolenaar /* 151f2d5c240SBram Moolenaar * Find an exported item in "sid" matching the name at "*argp". 152f2d5c240SBram Moolenaar * When it is a variable return the index. 153f2d5c240SBram Moolenaar * When it is a user function return "*ufunc". 154f2d5c240SBram Moolenaar * When not found returns -1 and "*ufunc" is NULL. 155f2d5c240SBram Moolenaar */ 156f2d5c240SBram Moolenaar int 157f2d5c240SBram Moolenaar find_exported( 158f2d5c240SBram Moolenaar int sid, 159f2d5c240SBram Moolenaar char_u **argp, 160f2d5c240SBram Moolenaar int *name_len, 161f2d5c240SBram Moolenaar ufunc_T **ufunc, 162f2d5c240SBram Moolenaar type_T **type) 163f2d5c240SBram Moolenaar { 164f2d5c240SBram Moolenaar char_u *name = *argp; 165f2d5c240SBram Moolenaar char_u *arg = *argp; 166f2d5c240SBram Moolenaar int cc; 167f2d5c240SBram Moolenaar int idx = -1; 168f2d5c240SBram Moolenaar svar_T *sv; 169f2d5c240SBram Moolenaar scriptitem_T *script = SCRIPT_ITEM(sid); 170f2d5c240SBram Moolenaar 171f2d5c240SBram Moolenaar // isolate one name 172fa29c8abSBram Moolenaar while (eval_isnamec(*arg)) 173f2d5c240SBram Moolenaar ++arg; 174f2d5c240SBram Moolenaar *name_len = (int)(arg - name); 175f2d5c240SBram Moolenaar 176f2d5c240SBram Moolenaar // find name in "script" 177f2d5c240SBram Moolenaar // TODO: also find script-local user function 178f2d5c240SBram Moolenaar cc = *arg; 179f2d5c240SBram Moolenaar *arg = NUL; 180f2d5c240SBram Moolenaar idx = get_script_item_idx(sid, name, FALSE); 181f2d5c240SBram Moolenaar if (idx >= 0) 182f2d5c240SBram Moolenaar { 183f2d5c240SBram Moolenaar sv = ((svar_T *)script->sn_var_vals.ga_data) + idx; 184f2d5c240SBram Moolenaar if (!sv->sv_export) 185f2d5c240SBram Moolenaar { 186f2d5c240SBram Moolenaar semsg(_("E1049: Item not exported in script: %s"), name); 187f2d5c240SBram Moolenaar *arg = cc; 188f2d5c240SBram Moolenaar return -1; 189f2d5c240SBram Moolenaar } 190f2d5c240SBram Moolenaar *type = sv->sv_type; 191f2d5c240SBram Moolenaar *ufunc = NULL; 192f2d5c240SBram Moolenaar } 193f2d5c240SBram Moolenaar else 194f2d5c240SBram Moolenaar { 195f2d5c240SBram Moolenaar char_u buffer[200]; 196f2d5c240SBram Moolenaar char_u *funcname; 197f2d5c240SBram Moolenaar 198f2d5c240SBram Moolenaar // it could be a user function. 199f2d5c240SBram Moolenaar if (STRLEN(name) < sizeof(buffer) - 10) 200f2d5c240SBram Moolenaar funcname = buffer; 201f2d5c240SBram Moolenaar else 202f2d5c240SBram Moolenaar { 203f2d5c240SBram Moolenaar funcname = alloc(STRLEN(name) + 10); 204f2d5c240SBram Moolenaar if (funcname == NULL) 205f2d5c240SBram Moolenaar { 206f2d5c240SBram Moolenaar *arg = cc; 207f2d5c240SBram Moolenaar return -1; 208f2d5c240SBram Moolenaar } 209f2d5c240SBram Moolenaar } 210f2d5c240SBram Moolenaar funcname[0] = K_SPECIAL; 211f2d5c240SBram Moolenaar funcname[1] = KS_EXTRA; 212f2d5c240SBram Moolenaar funcname[2] = (int)KE_SNR; 213f2d5c240SBram Moolenaar sprintf((char *)funcname + 3, "%ld_%s", (long)sid, name); 2144c17ad94SBram Moolenaar *ufunc = find_func(funcname, FALSE, NULL); 215f2d5c240SBram Moolenaar if (funcname != buffer) 216f2d5c240SBram Moolenaar vim_free(funcname); 217f2d5c240SBram Moolenaar 218f2d5c240SBram Moolenaar if (*ufunc == NULL) 219f2d5c240SBram Moolenaar { 220f2d5c240SBram Moolenaar semsg(_("E1048: Item not found in script: %s"), name); 221f2d5c240SBram Moolenaar *arg = cc; 222f2d5c240SBram Moolenaar return -1; 223f2d5c240SBram Moolenaar } 224f2d5c240SBram Moolenaar } 225f2d5c240SBram Moolenaar *arg = cc; 226f2d5c240SBram Moolenaar arg = skipwhite(arg); 227f2d5c240SBram Moolenaar *argp = arg; 228f2d5c240SBram Moolenaar 229f2d5c240SBram Moolenaar return idx; 230f2d5c240SBram Moolenaar } 231f2d5c240SBram Moolenaar 232f2d5c240SBram Moolenaar /* 2338a7d6542SBram Moolenaar * Handle an ":import" command and add the resulting imported_T to "gap", when 2348a7d6542SBram Moolenaar * not NULL, or script "import_sid" sn_imports. 2358a7d6542SBram Moolenaar * Returns a pointer to after the command or NULL in case of failure 2368a7d6542SBram Moolenaar */ 2378a7d6542SBram Moolenaar char_u * 2385269bd2aSBram Moolenaar handle_import(char_u *arg_start, garray_T *gap, int import_sid, void *cctx) 2398a7d6542SBram Moolenaar { 2408a7d6542SBram Moolenaar char_u *arg = arg_start; 2418a7d6542SBram Moolenaar char_u *cmd_end; 2428a7d6542SBram Moolenaar char_u *as_ptr = NULL; 2438a7d6542SBram Moolenaar char_u *from_ptr; 2448a7d6542SBram Moolenaar int as_len = 0; 2458a7d6542SBram Moolenaar int ret = FAIL; 2468a7d6542SBram Moolenaar typval_T tv; 2478a7d6542SBram Moolenaar int sid = -1; 2488a7d6542SBram Moolenaar int res; 2498a7d6542SBram Moolenaar 2508a7d6542SBram Moolenaar if (*arg == '{') 2518a7d6542SBram Moolenaar { 2528a7d6542SBram Moolenaar // skip over {item} list 2538a7d6542SBram Moolenaar while (*arg != NUL && *arg != '}') 2548a7d6542SBram Moolenaar ++arg; 2558a7d6542SBram Moolenaar if (*arg == '}') 2568a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 2578a7d6542SBram Moolenaar } 2588a7d6542SBram Moolenaar else 2598a7d6542SBram Moolenaar { 2608a7d6542SBram Moolenaar if (*arg == '*') 2618a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 262fa29c8abSBram Moolenaar else if (eval_isnamec1(*arg)) 2638a7d6542SBram Moolenaar { 264fa29c8abSBram Moolenaar while (eval_isnamec(*arg)) 2658a7d6542SBram Moolenaar ++arg; 2668a7d6542SBram Moolenaar arg = skipwhite(arg); 2678a7d6542SBram Moolenaar } 2688a7d6542SBram Moolenaar if (STRNCMP("as", arg, 2) == 0 && VIM_ISWHITE(arg[2])) 2698a7d6542SBram Moolenaar { 2708a7d6542SBram Moolenaar // skip over "as Name " 2718a7d6542SBram Moolenaar arg = skipwhite(arg + 2); 2728a7d6542SBram Moolenaar as_ptr = arg; 273fa29c8abSBram Moolenaar if (eval_isnamec1(*arg)) 274fa29c8abSBram Moolenaar while (eval_isnamec(*arg)) 2758a7d6542SBram Moolenaar ++arg; 2768a7d6542SBram Moolenaar as_len = (int)(arg - as_ptr); 2778a7d6542SBram Moolenaar arg = skipwhite(arg); 2785269bd2aSBram Moolenaar if (check_defined(as_ptr, as_len, cctx) == FAIL) 2795269bd2aSBram Moolenaar return NULL; 2808a7d6542SBram Moolenaar } 2818a7d6542SBram Moolenaar else if (*arg_start == '*') 2828a7d6542SBram Moolenaar { 2838a7d6542SBram Moolenaar emsg(_("E1045: Missing \"as\" after *")); 2848a7d6542SBram Moolenaar return NULL; 2858a7d6542SBram Moolenaar } 2868a7d6542SBram Moolenaar } 2878a7d6542SBram Moolenaar if (STRNCMP("from", arg, 4) != 0 || !VIM_ISWHITE(arg[4])) 2888a7d6542SBram Moolenaar { 289fa29c8abSBram Moolenaar emsg(_("E1070: Missing \"from\"")); 2908a7d6542SBram Moolenaar return NULL; 2918a7d6542SBram Moolenaar } 2928a7d6542SBram Moolenaar from_ptr = arg; 2938a7d6542SBram Moolenaar arg = skipwhite(arg + 4); 2948a7d6542SBram Moolenaar tv.v_type = VAR_UNKNOWN; 2958a7d6542SBram Moolenaar // TODO: should we accept any expression? 2968a7d6542SBram Moolenaar if (*arg == '\'') 2978a7d6542SBram Moolenaar ret = get_lit_string_tv(&arg, &tv, TRUE); 2988a7d6542SBram Moolenaar else if (*arg == '"') 2998a7d6542SBram Moolenaar ret = get_string_tv(&arg, &tv, TRUE); 3008a7d6542SBram Moolenaar if (ret == FAIL || tv.vval.v_string == NULL || *tv.vval.v_string == NUL) 3018a7d6542SBram Moolenaar { 302fa29c8abSBram Moolenaar emsg(_("E1071: Invalid string after \"from\"")); 3038a7d6542SBram Moolenaar return NULL; 3048a7d6542SBram Moolenaar } 3058a7d6542SBram Moolenaar cmd_end = arg; 3068a7d6542SBram Moolenaar 3078a7d6542SBram Moolenaar // find script tv.vval.v_string 3088a7d6542SBram Moolenaar if (*tv.vval.v_string == '.') 3098a7d6542SBram Moolenaar { 3108a7d6542SBram Moolenaar size_t len; 31121b9e977SBram Moolenaar scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); 3128a7d6542SBram Moolenaar char_u *tail = gettail(si->sn_name); 3138a7d6542SBram Moolenaar char_u *from_name; 3148a7d6542SBram Moolenaar 3158a7d6542SBram Moolenaar // Relative to current script: "./name.vim", "../../name.vim". 3168a7d6542SBram Moolenaar len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2; 3178a7d6542SBram Moolenaar from_name = alloc((int)len); 3188a7d6542SBram Moolenaar if (from_name == NULL) 3198a7d6542SBram Moolenaar { 3208a7d6542SBram Moolenaar clear_tv(&tv); 3218a7d6542SBram Moolenaar return NULL; 3228a7d6542SBram Moolenaar } 3238a7d6542SBram Moolenaar vim_strncpy(from_name, si->sn_name, tail - si->sn_name); 3248a7d6542SBram Moolenaar add_pathsep(from_name); 3258a7d6542SBram Moolenaar STRCAT(from_name, tv.vval.v_string); 3268a7d6542SBram Moolenaar simplify_filename(from_name); 3278a7d6542SBram Moolenaar 3288a7d6542SBram Moolenaar res = do_source(from_name, FALSE, DOSO_NONE, &sid); 3298a7d6542SBram Moolenaar vim_free(from_name); 3308a7d6542SBram Moolenaar } 3318a7d6542SBram Moolenaar else if (mch_isFullName(tv.vval.v_string)) 3328a7d6542SBram Moolenaar { 3338a7d6542SBram Moolenaar // Absolute path: "/tmp/name.vim" 3348a7d6542SBram Moolenaar res = do_source(tv.vval.v_string, FALSE, DOSO_NONE, &sid); 3358a7d6542SBram Moolenaar } 3368a7d6542SBram Moolenaar else 3378a7d6542SBram Moolenaar { 3388a7d6542SBram Moolenaar size_t len = 7 + STRLEN(tv.vval.v_string) + 1; 3398a7d6542SBram Moolenaar char_u *from_name; 3408a7d6542SBram Moolenaar 3418a7d6542SBram Moolenaar // Find file in "import" subdirs in 'runtimepath'. 3428a7d6542SBram Moolenaar from_name = alloc((int)len); 3438a7d6542SBram Moolenaar if (from_name == NULL) 3448a7d6542SBram Moolenaar { 3458a7d6542SBram Moolenaar clear_tv(&tv); 3468a7d6542SBram Moolenaar return NULL; 3478a7d6542SBram Moolenaar } 3488a7d6542SBram Moolenaar vim_snprintf((char *)from_name, len, "import/%s", tv.vval.v_string); 3498a7d6542SBram Moolenaar res = source_in_path(p_rtp, from_name, DIP_NOAFTER, &sid); 3508a7d6542SBram Moolenaar vim_free(from_name); 3518a7d6542SBram Moolenaar } 3528a7d6542SBram Moolenaar 3538a7d6542SBram Moolenaar if (res == FAIL || sid <= 0) 3548a7d6542SBram Moolenaar { 3558a7d6542SBram Moolenaar semsg(_("E1053: Could not import \"%s\""), tv.vval.v_string); 3568a7d6542SBram Moolenaar clear_tv(&tv); 3578a7d6542SBram Moolenaar return NULL; 3588a7d6542SBram Moolenaar } 3598a7d6542SBram Moolenaar clear_tv(&tv); 3608a7d6542SBram Moolenaar 3618a7d6542SBram Moolenaar if (*arg_start == '*') 3628a7d6542SBram Moolenaar { 3638a7d6542SBram Moolenaar imported_T *imported = new_imported(gap != NULL ? gap 36421b9e977SBram Moolenaar : &SCRIPT_ITEM(import_sid)->sn_imports); 3658a7d6542SBram Moolenaar 3668a7d6542SBram Moolenaar if (imported == NULL) 3678a7d6542SBram Moolenaar return NULL; 3688a7d6542SBram Moolenaar imported->imp_name = vim_strnsave(as_ptr, as_len); 3698a7d6542SBram Moolenaar imported->imp_sid = sid; 3708a7d6542SBram Moolenaar imported->imp_all = TRUE; 3718a7d6542SBram Moolenaar } 3728a7d6542SBram Moolenaar else 3738a7d6542SBram Moolenaar { 3748a7d6542SBram Moolenaar arg = arg_start; 3758a7d6542SBram Moolenaar if (*arg == '{') 3768a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 3778a7d6542SBram Moolenaar for (;;) 3788a7d6542SBram Moolenaar { 3798a7d6542SBram Moolenaar char_u *name = arg; 3808a7d6542SBram Moolenaar int name_len; 3818a7d6542SBram Moolenaar int idx; 3828a7d6542SBram Moolenaar imported_T *imported; 383f2d5c240SBram Moolenaar ufunc_T *ufunc = NULL; 384f2d5c240SBram Moolenaar type_T *type; 3858a7d6542SBram Moolenaar 386f2d5c240SBram Moolenaar idx = find_exported(sid, &arg, &name_len, &ufunc, &type); 3878a7d6542SBram Moolenaar 388f2d5c240SBram Moolenaar if (idx < 0 && ufunc == NULL) 3898a7d6542SBram Moolenaar return NULL; 3908a7d6542SBram Moolenaar 3915269bd2aSBram Moolenaar if (check_defined(name, name_len, cctx) == FAIL) 3925269bd2aSBram Moolenaar return NULL; 3935269bd2aSBram Moolenaar 3948a7d6542SBram Moolenaar imported = new_imported(gap != NULL ? gap 39521b9e977SBram Moolenaar : &SCRIPT_ITEM(import_sid)->sn_imports); 3968a7d6542SBram Moolenaar if (imported == NULL) 3978a7d6542SBram Moolenaar return NULL; 3988a7d6542SBram Moolenaar 3998a7d6542SBram Moolenaar // TODO: check for "as" following 4008a7d6542SBram Moolenaar // imported->imp_name = vim_strnsave(as_ptr, as_len); 4018a7d6542SBram Moolenaar imported->imp_name = vim_strnsave(name, name_len); 4028a7d6542SBram Moolenaar imported->imp_sid = sid; 4038a7d6542SBram Moolenaar if (idx >= 0) 4048a7d6542SBram Moolenaar { 405f2d5c240SBram Moolenaar imported->imp_type = type; 4068a7d6542SBram Moolenaar imported->imp_var_vals_idx = idx; 4078a7d6542SBram Moolenaar } 4088a7d6542SBram Moolenaar else 4098a7d6542SBram Moolenaar imported->imp_funcname = ufunc->uf_name; 4108a7d6542SBram Moolenaar 4118a7d6542SBram Moolenaar arg = skipwhite(arg); 4128a7d6542SBram Moolenaar if (*arg_start != '{') 4138a7d6542SBram Moolenaar break; 4148a7d6542SBram Moolenaar if (*arg == '}') 4158a7d6542SBram Moolenaar { 4168a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 4178a7d6542SBram Moolenaar break; 4188a7d6542SBram Moolenaar } 4198a7d6542SBram Moolenaar 4208a7d6542SBram Moolenaar if (*arg != ',') 4218a7d6542SBram Moolenaar { 4228a7d6542SBram Moolenaar emsg(_("E1046: Missing comma in import")); 4238a7d6542SBram Moolenaar return NULL; 4248a7d6542SBram Moolenaar } 4258a7d6542SBram Moolenaar arg = skipwhite(arg + 1); 4268a7d6542SBram Moolenaar } 4278a7d6542SBram Moolenaar if (arg != from_ptr) 4288a7d6542SBram Moolenaar { 429fa29c8abSBram Moolenaar // cannot happen, just in case the above has a flaw 4308a7d6542SBram Moolenaar emsg(_("E1047: syntax error in import")); 4318a7d6542SBram Moolenaar return NULL; 4328a7d6542SBram Moolenaar } 4338a7d6542SBram Moolenaar } 4348a7d6542SBram Moolenaar return cmd_end; 4358a7d6542SBram Moolenaar } 4368a7d6542SBram Moolenaar 4378a7d6542SBram Moolenaar #endif // FEAT_EVAL 438