diff options
Diffstat (limited to 'src/nvim/eval.c')
| -rw-r--r-- | src/nvim/eval.c | 216 |
1 files changed, 58 insertions, 158 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ed0b6290dc..48f9faa777 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -300,7 +300,6 @@ static ufunc_T dumuf; #define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j] #define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j] -#define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ #define VAR_SHORT_LEN 20 /* short variable name length */ #define FIXVAR_CNT 12 /* number of fixed variables */ @@ -6973,7 +6972,7 @@ get_func_tv ( * Return FAIL when the function can't be called, OK otherwise. * Also returns OK when an error was encountered while executing the function. */ -static int +int call_func ( char_u *funcname, /* name of the function */ int len, /* length of "name" */ @@ -7194,7 +7193,7 @@ static int non_zero_arg(typval_T *argvars) * Get the float value of "argvars[0]" into "f". * Returns FAIL when the argument is not a Number or Float. */ -static int get_float_arg(typval_T *argvars, float_T *f) +static inline int get_float_arg(typval_T *argvars, float_T *f) { if (argvars[0].v_type == VAR_FLOAT) { *f = argvars[0].vval.v_float; @@ -7208,14 +7207,34 @@ static int get_float_arg(typval_T *argvars, float_T *f) return FAIL; } +// Apply a floating point C function on a typval with one float_T. +// +// Some versions of glibc on i386 have an optimization that makes it harder to +// call math functions indirectly from inside an inlined function, causing +// compile-time errors. Avoid `inline` in that case. #3072 +#ifndef ARCH_32 +inline +#endif +static void float_op_wrapper(typval_T *argvars, typval_T *rettv, + float_T (*function)(float_T)) +{ + float_T f; + + rettv->v_type = VAR_FLOAT; + if (get_float_arg(argvars, &f) == OK) { + rettv->vval.v_float = function(f); + } else { + rettv->vval.v_float = 0.0; + } +} + /* * "abs(expr)" function */ static void f_abs(typval_T *argvars, typval_T *rettv) { if (argvars[0].v_type == VAR_FLOAT) { - rettv->v_type = VAR_FLOAT; - rettv->vval.v_float = fabs(argvars[0].vval.v_float); + float_op_wrapper(argvars, rettv, &fabs); } else { varnumber_T n; int error = FALSE; @@ -7235,13 +7254,7 @@ static void f_abs(typval_T *argvars, typval_T *rettv) */ static void f_acos(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = acos(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &acos); } /* @@ -7395,13 +7408,7 @@ static void f_argv(typval_T *argvars, typval_T *rettv) */ static void f_asin(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = asin(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &asin); } /* @@ -7409,13 +7416,7 @@ static void f_asin(typval_T *argvars, typval_T *rettv) */ static void f_atan(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = atan(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &atan); } /* @@ -7744,13 +7745,7 @@ static void f_call(typval_T *argvars, typval_T *rettv) */ static void f_ceil(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = ceil(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &ceil); } /* @@ -7954,13 +7949,7 @@ static void f_copy(typval_T *argvars, typval_T *rettv) */ static void f_cos(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = cos(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &cos); } /* @@ -7968,13 +7957,7 @@ static void f_cos(typval_T *argvars, typval_T *rettv) */ static void f_cosh(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = cosh(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &cosh); } /* @@ -8373,13 +8356,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv) */ static void f_exp(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = exp(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &exp); } /* @@ -8858,13 +8835,7 @@ static void f_float2nr(typval_T *argvars, typval_T *rettv) */ static void f_floor(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = floor(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &floor); } /* @@ -10042,9 +10013,7 @@ static void f_has(typval_T *argvars, typval_T *rettv) #endif "arabic", "autocmd", -#if defined(FEAT_BROWSE) && (defined(USE_FILE_CHOOSER) \ - || defined(FEAT_GUI_W32) \ - || defined(FEAT_GUI_MOTIF)) +#ifdef FEAT_BROWSE "browsefilter", #endif "byte_offset", @@ -11421,13 +11390,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) */ static void f_log(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = log(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &log); } /* @@ -11435,13 +11398,7 @@ static void f_log(typval_T *argvars, typval_T *rettv) */ static void f_log10(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = log10(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &log10); } @@ -11833,33 +11790,6 @@ static void f_min(typval_T *argvars, typval_T *rettv) max_min(argvars, rettv, FALSE); } - -/* - * Create the directory in which "dir" is located, and higher levels when - * needed. - */ -static int mkdir_recurse(char_u *dir, int prot) -{ - char_u *p; - char_u *updir; - int r = FAIL; - - /* Get end of directory name in "dir". - * We're done when it's "/" or "c:/". */ - p = path_tail_with_sep(dir); - if (p <= get_past_head(dir)) - return OK; - - /* If the directory exists we're done. Otherwise: create it.*/ - updir = vim_strnsave(dir, (int)(p - dir)); - if (os_isdir(updir)) - r = OK; - else if (mkdir_recurse(updir, prot) == OK) - r = vim_mkdir_emsg(updir, prot); - xfree(updir); - return r; -} - /* * "mkdir()" function */ @@ -11884,8 +11814,19 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv) if (argvars[1].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_UNKNOWN) prot = get_tv_number_chk(&argvars[2], NULL); - if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) - mkdir_recurse(dir, prot); + if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) { + char *failed_dir; + int ret = os_mkdir_recurse((char *) dir, prot, &failed_dir); + if (ret != 0) { + EMSG3(_(e_mkdir), failed_dir, os_strerror(ret)); + xfree(failed_dir); + rettv->vval.v_number = FAIL; + return; + } else { + rettv->vval.v_number = OK; + return; + } + } } rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot); } @@ -13356,7 +13297,7 @@ static void f_resolve(typval_T *argvars, typval_T *rettv) #endif p = get_tv_string(&argvars[0]); -#ifdef FEAT_SHORTCUT +#ifdef WIN32 { char_u *v = NULL; @@ -13692,13 +13633,7 @@ theend: */ static void f_round(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = round(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &round); } // "rpcnotify()" function @@ -14829,13 +14764,7 @@ static void f_simplify(typval_T *argvars, typval_T *rettv) */ static void f_sin(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = sin(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &sin); } /* @@ -14843,13 +14772,7 @@ static void f_sin(typval_T *argvars, typval_T *rettv) */ static void f_sinh(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = sinh(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &sinh); } /// struct used in the array that's given to qsort() @@ -15320,13 +15243,7 @@ static void f_split(typval_T *argvars, typval_T *rettv) */ static void f_sqrt(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = sqrt(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &sqrt); } /* @@ -15699,6 +15616,8 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv) modec = TOLOWER_ASC(mode[0]); if (modec != 'c' && modec != 'g') modec = 0; /* replace invalid with current */ + } else if (ui_rgb_attached()) { + modec = 'g'; } else { modec = 'c'; } @@ -16210,13 +16129,7 @@ static void f_test(typval_T *argvars, typval_T *rettv) */ static void f_tan(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = tan(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &tan); } /* @@ -16224,13 +16137,7 @@ static void f_tan(typval_T *argvars, typval_T *rettv) */ static void f_tanh(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - rettv->vval.v_float = tanh(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &tanh); } /* @@ -16378,14 +16285,7 @@ error: */ static void f_trunc(typval_T *argvars, typval_T *rettv) { - float_T f; - - rettv->v_type = VAR_FLOAT; - if (get_float_arg(argvars, &f) == OK) - /* trunc() is not in C90, use floor() or ceil() instead. */ - rettv->vval.v_float = f > 0 ? floor(f) : ceil(f); - else - rettv->vval.v_float = 0.0; + float_op_wrapper(argvars, rettv, &trunc); } /* |