/* Runs the command in shell and returns its output (joined standard output and * standard error streams). All trailing newline characters are stripped to * allow easy appending to command output. Returns the output. */ static var_t system_builtin(const call_info_t *call_info) { var_t result; char *cmd; FILE *cmd_stream; size_t cmd_out_len; var_val_t var_val; cmd = var_to_string(call_info->argv[0]); cmd_stream = read_cmd_output(cmd); free(cmd); ui_cancellation_enable(); var_val.string = read_nonseekable_stream(cmd_stream, &cmd_out_len); ui_cancellation_disable(); fclose(cmd_stream); if(var_val.string == NULL) { var_val.string = ""; return var_new(VTYPE_STRING, var_val); } /* Remove trailing new line characters. */ while(cmd_out_len != 0U && var_val.string[cmd_out_len - 1] == '\n') { var_val.string[cmd_out_len - 1] = '\0'; --cmd_out_len; } result = var_new(VTYPE_STRING, var_val); free(var_val.string); return result; }
return_code arrays_array(Object* o, Linked_list *args, Variable* eval_value, int as_constructor) { (void)o; (void)args; if(!as_constructor) { err_add(E_ERROR, OP_IMPOSSIBLE, "Can't use this built-in function (arrays.array) as a function"); return RC_ERROR; } // Nouvel objet array eval_value->type = T_OBJECT; eval_value->value.v_obj = var_new_object(NULL); // Nom d'objet : array eval_value->value.v_obj->name = "array"; eval_value->value.v_obj->name_h = ARRAY_HASH; // Array en lui même Array* ar = xcalloc(1, sizeof(Array)); eval_value->value.v_obj->data = (void*)ar; // Initialisation de l'array array_init(ar); // Fonction des strings Variable *v = var_new("add", str_hash("add"), T_FUNCTION_BUILTIN); v->value.v_func_builtin = arrays_array_add; v->container = &eval_value->value.v_obj->ec; v->container->object = eval_value->value.v_obj; linked_list_push(&(eval_value->value.v_obj->ec.variables), LLT_VARIABLE, (void*)v); v = var_new("get", str_hash("get"), T_FUNCTION_BUILTIN); v->value.v_func_builtin = arrays_array_get; v->container = &eval_value->value.v_obj->ec; v->container->object = eval_value->value.v_obj; linked_list_push(&(eval_value->value.v_obj->ec.variables), LLT_VARIABLE, (void*)v); v = var_new("pop", str_hash("pop"), T_FUNCTION_BUILTIN); v->value.v_func_builtin = arrays_array_pop; v->container = &eval_value->value.v_obj->ec; v->container->object = eval_value->value.v_obj; linked_list_push(&(eval_value->value.v_obj->ec.variables), LLT_VARIABLE, (void*)v); v = var_new("length", str_hash("length"), T_FUNCTION_BUILTIN); v->value.v_func_builtin = arrays_array_length; v->container = &eval_value->value.v_obj->ec; v->container->object = eval_value->value.v_obj; linked_list_push(&(eval_value->value.v_obj->ec.variables), LLT_VARIABLE, (void*)v); return RC_OK; }
/* Returns string representation of file type. */ 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) { #ifndef _WIN32 const mode_t mode = curr_view->dir_entry[fnum].mode; var_val.const_string = get_mode_str(mode); #else const FileType type = curr_view->dir_entry[fnum].type; var_val.const_string = get_type_str(type); #endif } 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; } }
struct t_value * exec_i_assign(struct t_exec *exec, struct t_icode *icode) { struct t_var *var; struct t_value *ret = NULL; struct t_value *opnd1, *opnd2; debug(2, "%s(): Begin\n", __FUNCTION__); opnd2 = list_pop(&exec->stack); assert(opnd2); opnd1 = list_pop(&exec->stack); assert(opnd1); debug(3, "%s(): Got operands from stack\n", __FUNCTION__); if (opnd2->type == VAL_VAR) { debug(3, "%s(): Fetching value for opnd2\n", __FUNCTION__); var = var_lookup(exec, opnd2->name); opnd2 = var->value; assert(opnd2); } if (opnd1->type != VAL_VAR) { fprintf(stderr, "Left side of assignment must be a variable. Got %s=%d instead.\n", value_types[opnd1->type], opnd1->intval); return NULL; } debug(3, "%s(): Looking up opnd1 var name=%s\n", __FUNCTION__, opnd1->name); var = var_lookup(exec, opnd1->name); if (var) { if (var->value->type != opnd2->type) { fprintf(stderr, "Type mismatch when assigning new value: %s = %s\n", opnd1->name, value_types[opnd2->type]); return NULL; } } else { var = var_new(opnd1->name, opnd2); list_push(&exec->vars, var); } debug(3, "%s(): Copying value to variable\n", __FUNCTION__); if (var->value->type == VAL_INT) { var->value->intval = opnd2->intval; ret = create_num_from_int(var->value->intval); list_push(&exec->values, ret); debug(3, "%s(): New int val: %d\n", __FUNCTION__, ret->intval); } else if (var->value->type == VAL_STRING) { var->value->stringval = opnd2->stringval; ret = var->value; debug(3, "%s(): Assigned string: %s\n", __FUNCTION__, ret->stringval); } else { fprintf(stderr, "Don't know how to assign %s type value\n", value_types[opnd2->type]); return NULL; } list_push(&exec->stack, ret); return ret; }
/* 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; } return -1; } /* Retrieves type of current pane as a string. */ static var_t getpanetype_builtin(const call_info_t *call_info) { FileView *const view = curr_view; var_val_t var_val; if(flist_custom_active(view)) { var_val.string = (view->custom.unsorted ? "very-custom" : "custom"); } else { var_val.string = "regular"; } return var_new(VTYPE_STRING, var_val); }
return_code strings_string(Object* o, Linked_list *args, Variable* eval_value, int as_constructor) { (void)o; (void)args; if(!as_constructor) { err_add(E_ERROR, OP_IMPOSSIBLE, "Can't use this built-in function (strings.string) as a function"); return RC_ERROR; } // Nouvel objet string eval_value->type = T_OBJECT; eval_value->value.v_obj = var_new_object(NULL); // Nom d'objet : string eval_value->value.v_obj->name = "string"; eval_value->value.v_obj->name_h = STRING_HASH; // String en lui même VK_String* vks = xcalloc(1, sizeof(VK_String)); eval_value->value.v_obj->data = (void*)vks; // Fonction des strings Variable *v = var_new("append", str_hash("append"), T_FUNCTION_BUILTIN); v->value.v_func_builtin = strings_string_append; v->container = &eval_value->value.v_obj->ec; v->container->object = eval_value->value.v_obj; linked_list_push(&(eval_value->value.v_obj->ec.variables), LLT_VARIABLE, (void*)v); v = var_new("length", str_hash("length"), T_FUNCTION_BUILTIN); v->value.v_func_builtin = strings_string_length; v->container = &eval_value->value.v_obj->ec; v->container->object = eval_value->value.v_obj; linked_list_push(&(eval_value->value.v_obj->ec.variables), LLT_VARIABLE, (void*)v); return RC_OK; }
struct instr * icall(char *fn, struct stack * args) { struct instr *i = malloc(sizeof *i); if (i == NULL) { perror("malloc"); return NULL; } i->optype = I_CAL; i->fn = fn; i->args = args; i->ret = elt_new(E_REG, reg_new(var_new(fn))); return i; }
/* Returns string after expanding expression. */ static var_t expand_builtin(const call_info_t *call_info) { var_t result; var_val_t var_val; char *str_val; str_val = var_to_string(call_info->argv[0]); var_val.string = expand_macros(str_val, NULL, NULL, 0); free(str_val); result = var_new(VTYPE_STRING, var_val); free(var_val.string); return result; }
// Initialisation de l'objet built-in string Object* arrays_init(Exec_context* ec_obj) { // Création de l'objet Object* o = var_new_object(NULL); (void)ec_obj; // Définition du type o->name = "arrays"; o->name_h = str_hash(o->name); // Ajout des fonctions Variable* v = var_new("array", str_hash("array"), T_FUNCTION_BUILTIN); v->value.v_func_builtin = arrays_array; v->container = &o->ec; v->container->object = o; linked_list_push(&(o->ec.variables), LLT_VARIABLE, (void*)v); return o; }
static int target_x86_add_local_var(target_x86_t *target_x86, char *name) { var_t *var; char addr[STR_SIZE]; int count; if( target_x86_get_local_var(target_x86, name) != NULL ) { return -1; } count = target_x86->array_local->count; sprintf(addr, "[ebp-0x%x]", 4+4*count); var = var_new(name, addr); array_add(target_x86->array_local, var); return 0; }
SLPError generic_set_val(struct xx_SLPAttributes *slp_attr, const char *tag, value_t *value, SLPInsertionPolicy policy, SLPType attr_type) /* Finds and sets the value named in tag. */ /* * slp_attr - The attr object to add to. * tag - the name of the tag to add to. * value - the already-allocated value object with fields set * policy - the policy to use when inserting. * attr_type - the type of the value being added. *****************************************************************************/ { var_t *var; /***** Create a new attribute. *****/ if ( (var = attr_val_find_str(slp_attr, tag)) == NULL) { /*** Couldn't find a value with this tag. Make a new one. ***/ var = var_new((char *)tag); if (var == NULL) { return SLP_MEMORY_ALLOC_FAILED; } var->type = attr_type; /** Add variable to list. **/ attr_add(slp_attr, var); } else { SLPError err; /*** The attribute already exists. ***/ /*** Verify type. ***/ err = attr_type_verify(slp_attr, var, attr_type); if (err == SLP_TYPE_ERROR && policy == SLP_REPLACE) { var_list_destroy(var); var->type = attr_type; } else if (err != SLP_OK) { value_free(value); return err; } } /***** Set value *****/ var_insert(var, value, policy); return SLP_OK; }
static var_t dummy(const call_info_t *call_info) { static const var_val_t var_val = { .string = "" }; called = 1; return var_new(VTYPE_STRING, var_val); } TEST(or_is_lazy) { ASSERT_OK("1 || a()", "1"); assert_false(called); } TEST(and_is_lazy) { ASSERT_OK("0 && a()", "0"); assert_false(called); } TEST(compares_are_lazy) { ASSERT_OK("0 && 1 < a()", "0"); assert_false(called); } TEST(negation_is_lazy) { ASSERT_OK("0 && -a()", "0"); assert_false(called); } TEST(not_is_lazy) { ASSERT_OK("0 && !a()", "0"); assert_false(called); }
int vis_particle( geometry_t *geometry, element_model_t *model, particle_t *particles, double gtime ) { double *f_x0 = NULL, *f_y0 = NULL, *f_z0 = NULL, *f_c0 = NULL; double *PartX, *PartY, *PartZ, *PartC, *PartI; double x, y, z, c, CAdd = 0.0, CScl = 1.0; double LX,LY,LZ, LC; double r = 0.05, *C; double x0,y0,x1,y1,z0,z1; double k1,k2,k3,k4; double t, dt, ddt; double CEPS = particles->Tolerance; int i, j, k, n, quick; double s = MAX(MAX(xmax-xmin,ymax-ymin),zmax-zmin); float pnt[3], vec[3]; if ( !GlobalOptions.StereoMode ) if ( particles->Material->Diffuse[3] < 1.0 ) { if ( GlobalPass != 0 ) return TRUE; } else if ( GlobalPass == 0 ) { return TRUE; } if ( particles->NofParticles < 1 ) return TRUE; if ( !particles->VectorData || !particles->VectorData[0]->f ) return TRUE; if ( !particles->ParticleData || !particles->ParticleData[0]->f ) return TRUE; f_x0 = particles->VectorData[0]->f; f_y0 = particles->VectorData[1]->f; f_z0 = particles->VectorData[2]->f; gra_set_material( particles->Material ); if ( particles->ColorData && particles->ColorData->f ) { f_c0 = particles->ColorData->f; CAdd = particles->ColorData->min; if ( particles->ColorData->max - particles->ColorData->min != 0.0 ) CScl = 1.0 / ( particles->ColorData->max - particles->ColorData->min ); else CScl = 1.0; gra_set_colormap( particles->ColorMap ); } else gra_set_colormap( NULL ); PartX = particles->ParticleData[0]->f; PartY = particles->ParticleData[1]->f; PartZ = particles->ParticleData[2]->f; PartC = particles->ParticleData[3]->f; PartI = particles->ParticleData[4]->f; n = particles->NofParticles; if ( particles->SaveNofParticles != n ) { { VARIABLE *var = var_new( "_particle_last", TYPE_DOUBLE,5,n ); particles->X = &M(var,0,0); particles->Y = &M(var,1,0); particles->Z = &M(var,2,0); particles->C = &M(var,3,0); particles->I = &M(var,4,0); } for( i=0; i<n; i++ ) { particles->X[i] = PartX[i]; particles->Y[i] = PartY[i]; particles->Z[i] = PartZ[i]; particles->C[i] = PartC[i]; particles->I[i] = PartI[i]; } particles->SaveNofParticles = n; } quick = (particles->LineStyle == line_style_line); quick |= epMouseDown && epMouseDownTakesTooLong; if ( quick ) { if ( particles->Style == particle_style_vector ) { gra_beg_lines(); } else { gra_polygon_mode( GRA_LINE ); } gra_sphere_quality( 1 ); if ( !(epMouseDown && epMouseDownTakesTooLong) ) gra_line_width( particles->LineWidth ); else gra_line_width( 1.0 ); } if ( !quick && (particles->LineStyle == line_style_cylinder) ) { gra_sphere_quality( particles->LineQuality ); } t = 0.0; for( i=0; i<n; i++ ) { if ( particles->ParticleData[4]->f[i]<0 ) continue; x = PartX[i]; y = PartY[i]; z = PartZ[i]; c = PartC[i]; if ( particles->Advance && !epMouseDown ) { particles->X[i] = x; particles->Y[i] = y; particles->Z[i] = z; particles->C[i] = c; particles->I[i] = PartI[i]; t = 0.0; while( t < particles->OutDT-CEPS ) { dt = MIN( particles->OutDT-t,particles->MaxDT ); while( TRUE ) { if ( dt < 1.0E-9 ) break; x0 = x1 = x; y0 = y1 = y; z0 = z1 = z; switch( particles->IntegMethod ) { case particle_integ_euler: vis_Euler( particles, model, i, &x0, &y0, &z0, &c, t, dt, f_x0, f_y0, f_z0, f_c0 ); if ( particles->IntegPolicy==particle_policy_adaptive ) { vis_Euler( particles, model, i, &x1, &y1, &z1, &c, t, dt / 2, f_x0, f_y0, f_z0, f_c0 ); vis_Euler( particles, model, i, &x1, &y1, &z1, &c, t + dt / 2, dt / 2, f_x0, f_y0, f_z0, f_c0 ); } break; case particle_integ_runge_kutta: vis_RungeKutta( particles, model, i, &x0, &y0, &z0, &c, t, dt, f_x0, f_y0, f_z0, f_c0 ); if ( particles->IntegPolicy==particle_policy_adaptive ) { vis_RungeKutta( particles, model, i, &x1, &y1, &z1, &c, t, dt / 2, f_x0, f_y0, f_z0, f_c0 ); vis_RungeKutta( particles, model, i, &x1, &y1, &z1, &c, t + dt / 2, dt / 2, f_x0, f_y0, f_z0, f_c0 ); } break; } if ( particles->IntegPolicy == particle_policy_fixed ) { x1 = x0; y1 = y0; z1 = z0; break; } if ( ABS(x0-x1) < CEPS && ABS(y0-y1) < CEPS && ABS(z0-z1) < CEPS ) break; dt /= 2; if ( BreakLoop ) break; } if ( BreakLoop ) break; t += dt; x = x1; y = y1; z = z1; if ( dt < 1.0E-9 ) { fprintf( stderr, "For Your record: stepping didn't succeed.\n" ); break; } if ( BreakLoop ) break; } if ( BreakLoop ) break; PartX[i] = x; PartY[i] = y; PartZ[i] = z; PartC[i] = c; } if ( BreakLoop ) break; if ( particles->Style == particle_style_vector ) { LX = particles->X[i]; LY = particles->Y[i]; LZ = particles->Z[i]; LC = particles->C[i]; LX = ( 2.0*(LX-xmin) - (xmax-xmin) ) / s; LY = ( 2.0*(LY-ymin) - (ymax-ymin) ) / s; LZ = ( 2.0*(LZ-zmin) - (zmax-zmin) ) / s; x = ( 2.0*(x-xmin) - (xmax-xmin) ) / s; y = ( 2.0*(y-ymin) - (ymax-ymin) ) / s; z = ( 2.0*(z-zmin) - (zmax-zmin) ) / s; #if 0 if ( i==185 ) { extern double viewx,viewy,viewz,tox,toy,toz,upx,upy,upz; viewx=LX; viewy=LY; viewz=LZ; tox=x; toy=y; toz=z; upx=0; if ( ABS(LX-x)>ABS(LY-y) || ABS(LZ-z)>ABS(LY-y) ) { upy=1; upz=0; } else { upy=0; upz=1; } continue; } if ( (i%10) ) continue; #endif pnt[0] = LX; pnt[1] = LY; pnt[2] = LZ; vec[0] = x - LX; vec[1] = y - LY; vec[2] = z - LZ; r = sqrt( vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2] ); gra_arrow( pnt,vec,CScl*(c-CAdd),particles->LineStyle, particles->ArrowStyle,0.1*particles->LineWidth*r ); } else { x = ( 2.0*(x-xmin) - (xmax-xmin) ) / s; y = ( 2.0*(y-ymin) - (ymax-ymin) ) / s; z = ( 2.0*(z-zmin) - (zmax-zmin) ) / s; c = CScl*(c-CAdd); gra_sphere( x,y,z,c,particles->LineWidth*r*c ); } if ( epMouseDown && ( i & 30 ) ) { if ( RealTime() - gtime > TooLong2 ) if ( ++epMouseDownTakesTooLong > 3 ) { if ( quick ) if ( particles->Style == particle_style_vector ) { gra_end_lines( ); } else { gra_polygon_mode( GRA_FILL ); } return FALSE; } else gtime = RealTime(); } } particles->Advance = FALSE; if ( quick ) if ( particles->Style == particle_style_vector ) { gra_end_lines( ); } else { gra_polygon_mode( GRA_FILL ); } return TRUE; }
/* 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 {
int main(int argc, char *argv[]) { /* TODO: refactor main() function */ static const int quit = 0; char dir[PATH_MAX]; char **files = NULL; int nfiles = 0; if(get_cwd(dir, sizeof(dir)) == NULL) { perror("getcwd"); return -1; } (void)vifm_chdir(dir); args_parse(&vifm_args, argc, argv, dir); args_process(&vifm_args, 1); if(strcmp(vifm_args.lwin_path, "-") == 0 || strcmp(vifm_args.rwin_path, "-") == 0) { files = read_stream_lines(stdin, &nfiles, 1, NULL, NULL); if(reopen_term_stdin() != 0) { return EXIT_FAILURE; } } (void)setlocale(LC_ALL, ""); srand(time(NULL)); cfg_init(); if(vifm_args.logging) { init_logger(1, vifm_args.startup_log_path); } init_filelists(); regs_init(); cfg_discover_paths(); reinit_logger(cfg.log_file); /* Commands module also initializes bracket notation and variables. */ init_commands(); init_builtin_functions(); update_path_env(1); if(init_status(&cfg) != 0) { puts("Error during session status initialization."); return -1; } /* Tell file type module what function to use to check availability of * external programs. */ ft_init(&external_command_exists); /* This should be called before loading any configuration file. */ ft_reset(curr_stats.exec_env_type == EET_EMULATOR_WITH_X); init_option_handlers(); if(!vifm_args.no_configs) { /* vifminfo must be processed this early so that it can restore last visited * directory. */ read_info_file(0); } ipc_init(vifm_args.server_name, &parse_received_arguments); /* Export chosen server name to parsing unit. */ { var_val_t value = { .string = (char *)ipc_get_name() }; var_t var = var_new(VTYPE_STRING, value); setvar("v:servername", var); var_free(var); } args_process(&vifm_args, 0); bg_init(); fops_init(&enter_prompt_mode, &prompt_msg_custom); set_view_path(&lwin, vifm_args.lwin_path); set_view_path(&rwin, vifm_args.rwin_path); if(need_to_switch_active_pane(vifm_args.lwin_path, vifm_args.rwin_path)) { swap_view_roles(); } load_initial_directory(&lwin, dir); load_initial_directory(&rwin, dir); /* Force split view when two paths are specified on command-line. */ if(vifm_args.lwin_path[0] != '\0' && vifm_args.rwin_path[0] != '\0') { curr_stats.number_of_windows = 2; } /* Prepare terminal for further operations. */ curr_stats.original_stdout = reopen_term_stdout(); if(curr_stats.original_stdout == NULL) { return -1; } if(!setup_ncurses_interface()) { return -1; } { const colmgr_conf_t colmgr_conf = { .max_color_pairs = COLOR_PAIRS, .max_colors = COLORS, .init_pair = &init_pair, .pair_content = &pair_content, .pair_in_use = &pair_in_use, .move_pair = &move_pair, }; colmgr_init(&colmgr_conf); } init_modes(); init_undo_list(&undo_perform_func, NULL, &ui_cancellation_requested, &cfg.undo_levels); load_view_options(curr_view); curr_stats.load_stage = 1; if(!vifm_args.no_configs) { load_scheme(); cfg_load(); if(strcmp(vifm_args.lwin_path, "-") == 0) { flist_custom_set(&lwin, "-", dir, files, nfiles); } else if(strcmp(vifm_args.rwin_path, "-") == 0) { flist_custom_set(&rwin, "-", dir, files, nfiles); } } /* Load colors in any case to load color pairs. */ cs_load_pairs(); cs_write(); setup_signals(); /* Ensure trash directories exist, it might not have been called during * configuration file sourcing if there is no `set trashdir=...` command. */ (void)set_trash_dir(cfg.trash_dir); check_path_for_file(&lwin, vifm_args.lwin_path, vifm_args.lwin_handle); check_path_for_file(&rwin, vifm_args.rwin_path, vifm_args.rwin_handle); curr_stats.load_stage = 2; /* Update histories of the views to ensure that their current directories, * which might have been set using command-line parameters, are stored in the * history. This is not done automatically as history manipulation should be * postponed until views are fully loaded, otherwise there is no correct * information about current file and relative cursor position. */ flist_hist_save(&lwin, NULL, NULL, -1); flist_hist_save(&rwin, NULL, NULL, -1); /* Trigger auto-commands for initial directories. */ vle_aucmd_execute("DirEnter", lwin.curr_dir, &lwin); vle_aucmd_execute("DirEnter", rwin.curr_dir, &rwin); update_screen(UT_FULL); modes_update(); /* Run startup commands after loading file lists into views, so that commands * like +1 work. */ exec_startup_commands(&vifm_args); curr_stats.load_stage = 3; event_loop(&quit); return 0; } /* Checks whether pair is being used at the moment. Returns non-zero if so and * zero otherwise. */ static int pair_in_use(short int pair) { int i; for(i = 0; i < MAXNUM_COLOR; ++i) { if(cfg.cs.pair[i] == pair || lwin.cs.pair[i] == pair || rwin.cs.pair[i] == pair) { return 1; } } return 0; }