/* Checks for relative position of current pane. Returns boolean value that * reflects state of specified location. */ static var_t paneisat_builtin(const call_info_t *call_info) { char *loc; int result; const int only = (curr_stats.number_of_windows == 1); const int vsplit = (curr_stats.split == VSPLIT); const int first = (curr_view == &lwin); loc = var_to_string(call_info->argv[0]); if(strcmp(loc, "top") == 0) { result = (only || vsplit || first); } else if(strcmp(loc, "bottom") == 0) { result = (only || vsplit || !first); } else if(strcmp(loc, "left") == 0) { result = (only || !vsplit || first); } else if(strcmp(loc, "right") == 0) { result = (only || !vsplit || !first); } else { result = 0; } free(loc); return var_from_bool(result); }
/* Checks current layout configuration. Returns boolean value that reflects * state of specified layout type. */ static var_t layoutis_builtin(const call_info_t *call_info) { char *type; int result; type = var_to_string(call_info->argv[0]); if(strcmp(type, "only") == 0) { result = (curr_stats.number_of_windows == 1); } else if(strcmp(type, "split") == 0) { result = (curr_stats.number_of_windows == 2); } else if(strcmp(type, "vsplit") == 0) { result = (curr_stats.number_of_windows == 2 && curr_stats.split == VSPLIT); } else if(strcmp(type, "hsplit") == 0) { result = (curr_stats.number_of_windows == 2 && curr_stats.split == HSPLIT); } else { result = 0; } free(type); return var_from_bool(result); }
/* Allows examining internal parameters from scripts to e.g. figure out * environment in which application is running. */ static var_t has_builtin(const call_info_t *call_info) { var_t result; char *const str_val = var_to_string(call_info->argv[0]); if(strcmp(str_val, "unix") == 0) { result = var_from_bool(get_env_type() == ET_UNIX); } else if(strcmp(str_val, "win") == 0) { result = var_from_bool(get_env_type() == ET_WIN); } else { result = var_false(); } free(str_val); return result; }
/* Checks whether executable exists at absolute path orin directories listed in * $PATH when path isn't absolute. Checks for various executable extensions on * Windows. Returns boolean value describing result of the check. */ static var_t executable_builtin(const call_info_t *call_info) { int exists; char *str_val; str_val = var_to_string(call_info->argv[0]); if(strpbrk(str_val, PATH_SEPARATORS) != NULL) { exists = executable_exists(str_val); } else { exists = (find_cmd_in_path(str_val, 0UL, NULL) == 0); } free(str_val); return var_from_bool(exists); }
/* Evaluates logical AND operation. All operands are evaluated lazily from left * to right. Returns zero on success, otherwise non-zero is returned. */ static int eval_and_op(int nops, expr_t ops[], var_t *result) { int val; int i; if(nops == 0) { *result = var_false(); return 0; } if(eval_expr(&ops[0]) != 0) { return 1; } if(nops == 1) { *result = var_clone(ops[0].value); return 0; } /* Conversion to integer so that strings are converted into numbers instead of * checked to be empty. */ val = var_to_integer(ops[0].value); for(i = 1; i < nops && val; ++i) { if(eval_expr(&ops[i]) != 0) { return 1; } val &= var_to_integer(ops[i].value); } *result = var_from_bool(val); return 0; }
/* Gets string representation of file type. Returns the string. */ static var_t filetype_builtin(const call_info_t *call_info) { char *str_val = var_to_string(call_info->argv[0]); const int fnum = get_fnum(str_val); var_val_t var_val = { .string = "" }; free(str_val); if(fnum >= 0) { const FileType type = curr_view->dir_entry[fnum].type; var_val.const_string = get_type_str(type); } return var_new(VTYPE_STRING, var_val); } /* Returns file type from position or -1 if the position has wrong value. */ static int get_fnum(const char position[]) { if(strcmp(position, ".") == 0) { return curr_view->list_pos; } else { return -1; } } /* Checks current layout configuration. Returns boolean value that reflects * state of specified layout type. */ static var_t layoutis_builtin(const call_info_t *call_info) { char *type; int result; type = var_to_string(call_info->argv[0]); if(strcmp(type, "only") == 0) { result = (curr_stats.number_of_windows == 1); } else if(strcmp(type, "split") == 0) { result = (curr_stats.number_of_windows == 2); } else if(strcmp(type, "vsplit") == 0) { result = (curr_stats.number_of_windows == 2 && curr_stats.split == VSPLIT); } else if(strcmp(type, "hsplit") == 0) { result = (curr_stats.number_of_windows == 2 && curr_stats.split == HSPLIT); } else { result = 0; } free(type); return var_from_bool(result); }
/* Evaluates invocation operation. All operands are evaluated beforehand. * Returns zero on success, otherwise non-zero is returned. */ static int eval_call_op(const char name[], int nops, expr_t ops[], var_t *result) { int i; for(i = 0; i < nops; ++i) { if(eval_expr(&ops[i]) != 0) { return 1; } } if(strcmp(name, "==") == 0) { assert(nops == 2 && "Must be two arguments."); *result = var_from_bool(compare_variables(EQ, ops[0].value, ops[1].value)); } else if(strcmp(name, "!=") == 0) { assert(nops == 2 && "Must be two arguments."); *result = var_from_bool(compare_variables(NE, ops[0].value, ops[1].value)); } else if(strcmp(name, "<") == 0) { assert(nops == 2 && "Must be two arguments."); *result = var_from_bool(compare_variables(LT, ops[0].value, ops[1].value)); } else if(strcmp(name, "<=") == 0) { assert(nops == 2 && "Must be two arguments."); *result = var_from_bool(compare_variables(LE, ops[0].value, ops[1].value)); } else if(strcmp(name, ">") == 0) { assert(nops == 2 && "Must be two arguments."); *result = var_from_bool(compare_variables(GT, ops[0].value, ops[1].value)); } else if(strcmp(name, ">=") == 0) { assert(nops == 2 && "Must be two arguments."); *result = var_from_bool(compare_variables(GE, ops[0].value, ops[1].value)); } else if(strcmp(name, ".") == 0) { *result = eval_concat(nops, ops); } else if(strcmp(name, "!") == 0) { assert(nops == 1 && "Must be single argument."); *result = var_from_bool(!var_to_integer(ops[0].value)); } else if(strcmp(name, "-") == 0 || strcmp(name, "+") == 0) { assert(nops == 1 && "Must be single argument."); var_val_t val = { .integer = var_to_integer(ops[0].value) }; if(name[0] == '-') { val.integer = -val.integer; } *result = var_new(VTYPE_INT, val); } else {