diff options
-rw-r--r-- | src/nvim/eval.c | 184 | ||||
-rw-r--r-- | src/nvim/eval/executor.c | 3 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 36 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 13 |
4 files changed, 130 insertions, 106 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7e40f5e828..d26ff5e41d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3531,8 +3531,6 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) int type_is = FALSE; /* TRUE for "is" and "isnot" */ int len = 2; long n1, n2; - char_u *s1, *s2; - char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; int ic; /* @@ -3737,31 +3735,33 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) case TYPE_NOMATCH: break; /* avoid gcc warning */ } } else { - s1 = get_tv_string_buf(rettv, buf1); - s2 = get_tv_string_buf(&var2, buf2); + char buf1[NUMBUFLEN]; + char buf2[NUMBUFLEN]; + const char *const s1 = tv_get_string_buf(rettv, buf1); + const char *const s2 = tv_get_string_buf(&var2, buf2); if (type != TYPE_MATCH && type != TYPE_NOMATCH) { - i = mb_strcmp_ic((bool)ic, (const char *)s1, (const char *)s2); + i = mb_strcmp_ic((bool)ic, s1, s2); } else { i = 0; } n1 = false; switch (type) { - case TYPE_EQUAL: n1 = (i == 0); break; - case TYPE_NEQUAL: n1 = (i != 0); break; - case TYPE_GREATER: n1 = (i > 0); break; - case TYPE_GEQUAL: n1 = (i >= 0); break; - case TYPE_SMALLER: n1 = (i < 0); break; - case TYPE_SEQUAL: n1 = (i <= 0); break; - - case TYPE_MATCH: - case TYPE_NOMATCH: - n1 = pattern_match(s2, s1, ic); - if (type == TYPE_NOMATCH) { - n1 = !n1; + case TYPE_EQUAL: n1 = (i == 0); break; + case TYPE_NEQUAL: n1 = (i != 0); break; + case TYPE_GREATER: n1 = (i > 0); break; + case TYPE_GEQUAL: n1 = (i >= 0); break; + case TYPE_SMALLER: n1 = (i < 0); break; + case TYPE_SEQUAL: n1 = (i <= 0); break; + + case TYPE_MATCH: + case TYPE_NOMATCH: { + n1 = pattern_match((char_u *)s2, (char_u *)s1, ic); + if (type == TYPE_NOMATCH) { + n1 = !n1; + } + break; } - break; - - case TYPE_UNKNOWN: break; /* avoid gcc warning */ + case TYPE_UNKNOWN: break; // Avoid gcc warning. } } tv_clear(rettv); @@ -3794,8 +3794,6 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) int op; long n1, n2; float_T f1 = 0, f2 = 0; - char_u *s1, *s2; - char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; char_u *p; /* @@ -3842,14 +3840,17 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) * Compute the result. */ if (op == '.') { - s1 = get_tv_string_buf(rettv, buf1); /* already checked */ - s2 = get_tv_string_buf_chk(&var2, buf2); - if (s2 == NULL) { // Type error ? + char buf1[NUMBUFLEN]; + char_u buf2[NUMBUFLEN]; + // s1 already checked + const char *const s1 = tv_get_string_buf(rettv, buf1); + const char *const s2 = (const char *)get_tv_string_buf_chk(&var2, buf2); + if (s2 == NULL) { // Type error? tv_clear(rettv); tv_clear(&var2); return FAIL; } - p = concat_str(s1, s2); + p = concat_str((const char_u *)s1, (const char_u *)s2); tv_clear(rettv); rettv->v_type = VAR_STRING; rettv->vval.v_string = p; @@ -7565,20 +7566,21 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_cscope_connection(typval_T *argvars, typval_T *rettv, FunPtr fptr) { int num = 0; - char_u *dbpath = NULL; - char_u *prepend = NULL; - char_u buf[NUMBUFLEN]; + const char *dbpath = NULL; + const char *prepend = NULL; + char buf[NUMBUFLEN]; if (argvars[0].v_type != VAR_UNKNOWN && argvars[1].v_type != VAR_UNKNOWN) { num = (int)get_tv_number(&argvars[0]); - dbpath = (char_u *)tv_get_string(&argvars[1]); + dbpath = tv_get_string(&argvars[1]); if (argvars[2].v_type != VAR_UNKNOWN) { - prepend = get_tv_string_buf(&argvars[2], buf); + prepend = tv_get_string_buf(&argvars[2], buf); } } - rettv->vval.v_number = cs_connection(num, dbpath, prepend); + rettv->vval.v_number = cs_connection(num, (char_u *)dbpath, + (char_u *)prepend); } /// "cursor(lnum, col)" function, or @@ -7661,9 +7663,6 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr) // "delete()" function static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u nbuf[NUMBUFLEN]; - char_u *flags; - rettv->vval.v_number = -1; if (check_restricted() || check_secure()) { return; @@ -7675,19 +7674,21 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } + char nbuf[NUMBUFLEN]; + const char *flags; if (argvars[1].v_type != VAR_UNKNOWN) { - flags = get_tv_string_buf(&argvars[1], nbuf); + flags = tv_get_string_buf(&argvars[1], nbuf); } else { - flags = (char_u *)""; + flags = ""; } if (*flags == NUL) { // delete a file rettv->vval.v_number = os_remove(name) == 0 ? 0 : -1; - } else if (STRCMP(flags, "d") == 0) { + } else if (strcmp(flags, "d") == 0) { // delete an empty directory rettv->vval.v_number = os_rmdir(name) == 0 ? 0 : -1; - } else if (STRCMP(flags, "rf") == 0) { + } else if (strcmp(flags, "rf") == 0) { // delete a directory recursively rettv->vval.v_number = delete_recursive(name); } else { @@ -7905,11 +7906,11 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u buf[NUMBUFLEN]; + char buf[NUMBUFLEN]; rettv->vval.v_string = vim_strsave_escaped( (const char_u *)tv_get_string(&argvars[0]), - get_tv_string_buf(&argvars[1], buf)); + (const char_u *)tv_get_string_buf(&argvars[1], buf)); rettv->v_type = VAR_STRING; } @@ -8253,19 +8254,18 @@ static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u nbuf[NUMBUFLEN]; - - /* This is not allowed in the sandbox. If the commands would still be - * executed in the sandbox it would be OK, but it probably happens later, - * when "sandbox" is no longer set. */ - if (check_secure()) + // This is not allowed in the sandbox. If the commands would still be + // executed in the sandbox it would be OK, but it probably happens later, + // when "sandbox" is no longer set. + if (check_secure()) { return; + } const char *const keys = tv_get_string(&argvars[0]); - + char nbuf[NUMBUFLEN]; const char *flags = NULL; if (argvars[1].v_type != VAR_UNKNOWN) { - flags = (const char *)get_tv_string_buf(&argvars[1], nbuf); + flags = tv_get_string_buf(&argvars[1], nbuf); } nvim_feedkeys(cstr_as_string((char *)keys), @@ -10740,11 +10740,11 @@ static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr) const char *mode; const char *const name = tv_get_string(&argvars[0]); bool abbr = false; - char_u buf[NUMBUFLEN]; + char buf[NUMBUFLEN]; if (argvars[1].v_type == VAR_UNKNOWN) { mode = "nvo"; } else { - mode = (const char *)get_tv_string_buf(&argvars[1], buf); + mode = tv_get_string_buf(&argvars[1], buf); if (argvars[2].v_type != VAR_UNKNOWN) { abbr = get_tv_number(&argvars[2]); } @@ -10763,17 +10763,16 @@ static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) { HistoryType histype; - char_u *str; - char_u buf[NUMBUFLEN]; rettv->vval.v_number = false; if (check_restricted() || check_secure()) { return; } - str = get_tv_string_chk(&argvars[0]); // NULL on type error + char_u *str = get_tv_string_chk(&argvars[0]); // NULL on type error histype = str != NULL ? get_histtype(str, STRLEN(str), false) : HIST_INVALID; if (histype != HIST_INVALID) { - str = get_tv_string_buf(&argvars[1], buf); + char buf[NUMBUFLEN]; + str = (char_u *)tv_get_string_buf(&argvars[1], buf); if (*str != NUL) { init_history(); add_to_history(histype, str, false, NUL); @@ -10789,7 +10788,6 @@ static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) { int n; - char_u buf[NUMBUFLEN]; char_u *str; str = get_tv_string_chk(&argvars[0]); // NULL on type error @@ -10801,11 +10799,12 @@ static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else if (argvars[1].v_type == VAR_NUMBER) { // index given: remove that entry n = del_history_idx(get_histtype(str, STRLEN(str), false), - (int) get_tv_number(&argvars[1])); + (int)get_tv_number(&argvars[1])); } else { // string given: remove all matching entries + char buf[NUMBUFLEN]; n = del_history_entry(get_histtype(str, STRLEN(str), false), - get_tv_string_buf(&argvars[1], buf)); + (char_u *)tv_get_string_buf(&argvars[1], buf)); } rettv->vval.v_number = n; } @@ -10895,12 +10894,12 @@ static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_string = NULL; const char *const str = tv_get_string(&argvars[0]); - char_u buf1[NUMBUFLEN]; + char buf1[NUMBUFLEN]; char_u *const from = enc_canonize(enc_skip( - get_tv_string_buf(&argvars[1], buf1))); - char_u buf2[NUMBUFLEN]; + (char_u *)tv_get_string_buf(&argvars[1], buf1))); + char buf2[NUMBUFLEN]; char_u *const to = enc_canonize(enc_skip( - get_tv_string_buf(&argvars[2], buf2))); + (char_u *)tv_get_string_buf(&argvars[2], buf2))); vimconv.vc_type = CONV_NONE; convert_setup(&vimconv, from, to); @@ -10983,7 +10982,6 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) char_u *prompt = get_tv_string_chk(&argvars[0]); char_u *p = NULL; int c; - char_u buf[NUMBUFLEN]; int cmd_silent_save = cmd_silent; char_u *defstr = (char_u *)""; int xp_type = EXPAND_NOTHING; @@ -11013,9 +11011,11 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) cmdline_row = msg_row; if (argvars[1].v_type != VAR_UNKNOWN) { + char_u buf[NUMBUFLEN]; defstr = get_tv_string_buf_chk(&argvars[1], buf); - if (defstr != NULL) + if (defstr != NULL) { stuffReadbuffSpec(defstr); + } if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) { char_u *xp_name; @@ -11026,8 +11026,9 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) rettv->vval.v_string = NULL; xp_name = get_tv_string_buf_chk(&argvars[2], buf); - if (xp_name == NULL) + if (xp_name == NULL) { return; + } xp_namelen = (int)STRLEN(xp_name); @@ -11047,9 +11048,11 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) } if (inputdialog && rettv->vval.v_string == NULL && argvars[1].v_type != VAR_UNKNOWN - && argvars[2].v_type != VAR_UNKNOWN) - rettv->vval.v_string = vim_strsave(get_tv_string_buf( - &argvars[2], buf)); + && argvars[2].v_type != VAR_UNKNOWN) { + char buf[NUMBUFLEN]; + rettv->vval.v_string = (char_u *)xstrdup(tv_get_string_buf( + &argvars[2], buf)); + } xfree(xp_arg); @@ -12535,21 +12538,21 @@ static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u *dir; - char_u buf[NUMBUFLEN]; int prot = 0755; rettv->vval.v_number = FAIL; if (check_restricted() || check_secure()) return; - dir = get_tv_string_buf(&argvars[0], buf); - if (*dir == NUL) + char buf[NUMBUFLEN]; + const char *const dir = tv_get_string_buf(&argvars[0], buf); + if (*dir == NUL) { rettv->vval.v_number = FAIL; - else { - if (*path_tail(dir) == NUL) - /* remove trailing slashes */ - *path_tail_with_sep(dir) = NUL; + } else { + if (*path_tail((char_u *)dir) == NUL) { + // Remove trailing slashes. + *path_tail_with_sep((char_u *)dir) = NUL; + } if (argvars[1].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_UNKNOWN) { @@ -12557,7 +12560,7 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (prot != -1 && strcmp(tv_get_string(&argvars[1]), "p") == 0) { char *failed_dir; - int ret = os_mkdir_recurse((char *) dir, prot, &failed_dir); + int ret = os_mkdir_recurse(dir, prot, &failed_dir); if (ret != 0) { EMSG3(_(e_mkdir), failed_dir, os_strerror(ret)); xfree(failed_dir); @@ -12840,14 +12843,13 @@ static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; { - char_u buf[NUMBUFLEN]; int len; int saved_did_emsg = did_emsg; - char *fmt; - /* Get the required length, allocate the buffer and do it for real. */ - did_emsg = FALSE; - fmt = (char *)get_tv_string_buf(&argvars[0], buf); + // Get the required length, allocate the buffer and do it for real. + did_emsg = false; + char buf[NUMBUFLEN]; + const char *fmt = tv_get_string_buf(&argvars[0], buf); len = vim_vsnprintf(NULL, 0, fmt, dummy_ap, argvars + 1); if (!did_emsg) { char *s = xmalloc(len + 1); @@ -13270,14 +13272,13 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u buf[NUMBUFLEN]; - if (check_restricted() || check_secure()) { rettv->vval.v_number = -1; } else { + char buf[NUMBUFLEN]; rettv->vval.v_number = vim_rename( - (char_u *)tv_get_string(&argvars[0]), - get_tv_string_buf(&argvars[1], buf)); + (const char_u *)tv_get_string(&argvars[0]), + (const char_u *)tv_get_string_buf(&argvars[1], buf)); } } @@ -16003,8 +16004,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) int modec; if (argvars[2].v_type != VAR_UNKNOWN) { char modebuf[NUMBUFLEN]; - const char *const mode = (const char *)get_tv_string_buf(&argvars[2], - (char_u *)modebuf); + const char *const mode = tv_get_string_buf(&argvars[2], modebuf); modec = TOLOWER_ASC(mode[0]); if (modec != 'c' && modec != 'g') { modec = 0; // Replace invalid with current. @@ -18530,14 +18530,6 @@ static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf) // TODO(ZyX-I): move to eval/typval -char_u *get_tv_string_buf(const typval_T *varp, char_u *buf) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT -{ - char_u *const res = get_tv_string_buf_chk(varp, buf); - - return res != NULL ? res : (char_u *)""; -} - /// Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE! char_u *get_tv_string_chk(const typval_T *varp) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index 41b55e4a57..d2d0873792 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -80,7 +80,8 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, const char *tvs = tv_get_string(tv1); char numbuf[NUMBUFLEN]; char *const s = (char *)concat_str( - (const char_u *)tvs, get_tv_string_buf(tv2, (char_u *)numbuf)); + (const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2, + numbuf)); tv_clear(tv1); tv1->v_type = VAR_STRING; tv1->vval.v_string = (char_u *)s; diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index cbeb2e059c..2c2d0ecaab 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -1127,7 +1127,7 @@ const char *tv_dict_get_string_buf(dict_T *const d, const char *const key, if (di == NULL) { return NULL; } - return (const char *)get_tv_string_buf(&di->di_tv, (char_u *)numbuf); + return tv_get_string_buf(&di->di_tv, numbuf); } /// Get a function from a dictionary @@ -1948,8 +1948,8 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, case VAR_STRING: { char buf1[NUMBUFLEN]; char buf2[NUMBUFLEN]; - const char *s1 = (const char *)get_tv_string_buf(tv1, (char_u *)buf1); - const char *s2 = (const char *)get_tv_string_buf(tv2, (char_u *)buf2); + const char *s1 = tv_get_string_buf(tv1, buf1); + const char *s2 = tv_get_string_buf(tv2, buf2); return mb_strcmp_ic((bool)ic, s1, s2) == 0; } case VAR_SPECIAL: { @@ -2021,7 +2021,7 @@ bool tv_check_str_or_nr(const typval_T *const tv) /// /// @warning For number and special values it uses a single, static buffer. It /// may be used only once, next call to get_tv_string may reuse it. Use -/// get_tv_string_buf() if you need to use tv_get_string() output after +/// tv_get_string_buf() if you need to use tv_get_string() output after /// calling it again. /// /// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but @@ -2035,6 +2035,30 @@ bool tv_check_str_or_nr(const typval_T *const tv) const char *tv_get_string(const typval_T *const varp) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT { - static char_u mybuf[NUMBUFLEN]; - return (const char *)get_tv_string_buf((typval_T *)varp, mybuf); + static char mybuf[NUMBUFLEN]; + return tv_get_string_buf((typval_T *)varp, mybuf); +} + +/// Get the string value of a variable +/// +/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but +/// return NULL on error. +/// +/// @param[in] varp Varible to get value of. +/// @param buf Buffer used to hold numbers and special variables converted to +/// string. When function encounters one of these stringified value +/// will be written to buf and buf will be returned. +/// +/// Buffer must have NUMBUFLEN size. +/// +/// @return Variable value if it is VAR_STRING variable, number converted to +/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or empty +/// string. +const char *tv_get_string_buf(const typval_T *const varp, char *const buf) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT +{ + const char *const res = (const char *)get_tv_string_buf_chk( + (typval_T *)varp, (char_u *)buf); + + return res != NULL ? res : ""; } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 5209dfc451..6b661cff11 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7724,7 +7724,7 @@ static void ex_mkrc(exarg_T *eap) /* When using 'viewdir' may have to create the directory. */ if (using_vdir && !os_isdir(p_vdir)) { - vim_mkdir_emsg(p_vdir, 0755); + vim_mkdir_emsg((const char *)p_vdir, 0755); } fd = open_exfile((char_u *) fname, eap->forceit, WRITEBIN); @@ -7836,10 +7836,17 @@ static void ex_mkrc(exarg_T *eap) xfree(viewFile); } -int vim_mkdir_emsg(char_u *name, int prot) +/// Try creating a directory, give error message on failure +/// +/// @param[in] name Directory to create. +/// @param[in] prot Directory permissions. +/// +/// @return OK in case of success, FAIL otherwise. +int vim_mkdir_emsg(const char *const name, const int prot) + FUNC_ATTR_NONNULL_ALL { int ret; - if ((ret = os_mkdir((char *)name, prot)) != 0) { + if ((ret = os_mkdir(name, prot)) != 0) { EMSG3(_(e_mkdir), name, os_strerror(ret)); return FAIL; } |