static void refresh (PsppireDialogAction *da) { PsppireDialogActionIndepSamps *act = PSPPIRE_DIALOG_ACTION_INDEP_SAMPS (da); GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (act->test_vars_tv)); act->group_defn = GROUPS_UNDEF; if (act->grp_var) { int width = var_get_width (act->grp_var); value_destroy (&act->cut_point, width); value_destroy (&act->grp_val[0], width); value_destroy (&act->grp_val[1], width); act->grp_var = NULL; } psppire_value_entry_set_variable (PSPPIRE_VALUE_ENTRY (act->dg_grp_entry[0]), NULL); psppire_value_entry_set_variable (PSPPIRE_VALUE_ENTRY (act->dg_grp_entry[1]), NULL); psppire_value_entry_set_variable (PSPPIRE_VALUE_ENTRY (act->dg_cut_point_entry), NULL); gtk_entry_set_text (GTK_ENTRY (act->group_var_entry), ""); gtk_list_store_clear (GTK_LIST_STORE (model)); gtk_widget_set_sensitive (act->define_groups_button, FALSE); }
static VALUE ruby_function_proxy(VALUE self, VALUE _args) { ID id = rb_frame_last_func(); value_t* value = dict_lookup(global->functions, (void*)id); if(!value) { language_error(global->li, "[ruby] couldn't retrieve constant %s", rb_id2name(id)); return Qnil; } if(value->type == TYPE_FUNCTION) { log_dbg("[ruby] calling function %s", rb_id2name(id)); value_t*args = ruby_to_value(_args); value_t*ret = value->call(value, args); value_destroy(args); volatile VALUE r = value_to_ruby(ret); value_destroy(ret); log_dbg("[rb] returning from callback"); return r; } else { log_dbg("[ruby] retrieving constant %s (%s)", rb_id2name(id), type_to_string(value->type)); volatile VALUE r = value_to_ruby(value); return r; } return Qnil; }
/* Parse all the labels for the VAR_CNT variables in VARS and add the specified labels to those variables. */ static int get_label (struct lexer *lexer, struct variable **vars, size_t var_cnt, const char *dict_encoding) { /* Parse all the labels and add them to the variables. */ do { enum { MAX_LABEL_LEN = 255 }; int width = var_get_width (vars[0]); union value value; struct string label; size_t trunc_len; size_t i; /* Set value. */ value_init (&value, width); if (!parse_value (lexer, &value, vars[0])) { value_destroy (&value, width); return 0; } lex_match (lexer, T_COMMA); /* Set label. */ if (lex_token (lexer) != T_ID && !lex_force_string (lexer)) { value_destroy (&value, width); return 0; } ds_init_substring (&label, lex_tokss (lexer)); trunc_len = utf8_encoding_trunc_len (ds_cstr (&label), dict_encoding, MAX_LABEL_LEN); if (ds_length (&label) > trunc_len) { msg (SW, _("Truncating value label to %d bytes."), MAX_LABEL_LEN); ds_truncate (&label, trunc_len); } for (i = 0; i < var_cnt; i++) var_replace_value_label (vars[i], &value, ds_cstr (&label)); ds_destroy (&label); value_destroy (&value, width); lex_get (lexer); lex_match (lexer, T_COMMA); } while (lex_token (lexer) != T_SLASH && lex_token (lexer) != T_ENDCMD); return 1; }
kj_internal void vm_op_add(vm_t *vm, value_t *dest, value_t const *lhs, value_t const *rhs) { switch (lhs->type) { case KJ_TYPE_STRING: { if (rhs->type != KJ_TYPE_STRING) goto error; /* * create a new string by concatenating lhs and rhs. create a local, temporary value first and then * destroy dest as dest might be lhs or rhs. */ value_t temp = { 0 }; /* make temp a string*/ value_new_string(&temp, vm->allocator, lhs->string->length + rhs->string->length); /* copy lhs */ memcpy(temp.string->data, lhs->string->data, lhs->string->length); /* copy rhs */ memcpy(temp.string->data + lhs->string->length, rhs->string->data, rhs->string->length + 1); value_destroy(dest, vm->allocator); *dest = temp; break; } DEFAULT_BINOP_CASES(+) } }
kj_internal void vm_op_mul(vm_t *vm, value_t *dest, value_t const *lhs, value_t const *rhs) { switch (lhs->type) { case KJ_TYPE_STRING: { if (rhs->type != KJ_TYPE_INT && rhs->type != KJ_TYPE_REAL) goto error; kj_integer repetitions = value_to_int(rhs); if (repetitions < 0) { vm_throw(vm, "rhs value of string by integer multiplication must be non negative, it is " KJ_INTEGER_PRF ".", repetitions); } uint dest_length = (uint)(lhs->string->length * repetitions); value_t temp = { 0 }; value_new_string(&temp, vm->allocator, dest_length); /* copy lhs into dest 'rhs' times */ for (kj_integer i = 0; i < repetitions; ++i) { memcpy(temp.string->data + lhs->string->length * i, lhs->string->data, lhs->string->length); } temp.string->data[dest_length] = '\0'; value_destroy(dest, vm->allocator); *dest = temp; break; } DEFAULT_BINOP_CASES(*) } }
size_t value_size(struct value *val, struct value_dict *arguments) { if (val->size != (size_t)-1) return val->size; if (val->type->type != ARGTYPE_ARRAY) return val->size = type_sizeof(val->inferior, val->type); struct value length; if (expr_eval(val->type->u.array_info.length, val, arguments, &length) < 0) return (size_t)-1; size_t l; int o = value_extract_word(&length, (long *)&l, arguments); value_destroy(&length); if (o < 0) return (size_t)-1; size_t elt_size = type_sizeof(val->inferior, val->type->u.array_info.elt_type); if (elt_size == (size_t)-1) return (size_t)-1; return val->size = elt_size * l; }
static int fetch_simple_param(enum tof type, struct process *proc, struct fetch_context *context, struct value_dict *arguments, struct arg_type_info *info, int own, struct value *valuep) { /* Arrays decay into pointers per C standard. We check for * this here, because here we also capture arrays that come * from parameter packs. */ if (info->type == ARGTYPE_ARRAY) { struct arg_type_info *tmp = malloc(sizeof(*tmp)); if (tmp != NULL) { type_init_pointer(tmp, info, own); tmp->lens = info->lens; info = tmp; own = 1; } } struct value value; value_init(&value, proc, NULL, info, own); if (fetch_arg_next(context, type, proc, info, &value) < 0) return -1; if (val_dict_push_next(arguments, &value) < 0) { value_destroy(&value); return -1; } if (valuep != NULL) *valuep = value; return 0; }
/* Return TRUE if VE contains a text which is not valid for VAR or if it contains the SYSMIS value */ static gboolean value_entry_contains_invalid (PsppireValueEntry *ve, const struct variable *var) { gboolean result = FALSE; if (var) { union value val; const int width = var_get_width (var); value_init (&val, width); if ( psppire_value_entry_get_value (ve, &val, width)) { if (var_is_value_missing (var, &val, MV_SYSTEM)) { result = TRUE; } } else result = TRUE; value_destroy (&val, width); } return result; }
/** Destroy an argument list. * @param list List to destroy. */ void value_list_destroy(value_list_t *list) { for (size_t i = 0; i < list->count; i++) value_destroy(&list->values[i]); free(list->values); free(list); }
/* Create value from a referenced array */ int value_create_from_refarray(struct ref_array *raw_lines, struct ref_array *raw_lengths, uint32_t line, uint32_t origin, uint32_t key_len, uint32_t boundary, struct ini_comment *ic, struct value_obj **vo) { int error = EOK; struct value_obj *new_vo = NULL; TRACE_FLOW_ENTRY(); if ((!raw_lines) || (!raw_lengths) || (!vo)) { TRACE_ERROR_NUMBER("Invalid argument", EINVAL); return EINVAL; } new_vo = malloc(sizeof(struct value_obj)); if (!new_vo) { TRACE_ERROR_NUMBER("No memory", ENOMEM); return ENOMEM; } /* We are not using references here since * it will be inconsistent with the way * how comment is handled. * We could have added references here and make * comment keep references but it seems to be * and overhead in this case. */ new_vo->raw_lines = raw_lines; new_vo->raw_lengths = raw_lengths; new_vo->origin = origin; new_vo->line = line; new_vo->keylen = key_len; new_vo->boundary = boundary; new_vo->ic = ic; error = value_unfold(new_vo->raw_lines, new_vo->raw_lengths, &(new_vo->unfolded)); if (error) { TRACE_ERROR_NUMBER("Failed to unfold", error); value_destroy(new_vo); return error; } TRACE_INFO_STRING("Unfolded:", (const char *)simplebuffer_get_buf(new_vo->unfolded)); *vo = new_vo; TRACE_FLOW_EXIT(); return error; }
/* Called whenever the group variable entry widget's contents change */ static void on_grp_var_change (GtkEntry *entry, PsppireDialogActionIndepSamps *act) { PsppireDialogAction *da = PSPPIRE_DIALOG_ACTION (act); const gchar *text = gtk_entry_get_text (entry); const struct variable *v = psppire_dict_lookup_var (da->dict, text); gtk_widget_set_sensitive (act->define_groups_button, v != NULL); if (act->grp_var) { int width = var_get_width (act->grp_var); value_destroy (&act->cut_point, width); value_destroy (&act->grp_val[0], width); value_destroy (&act->grp_val[1], width); } if (v) { const int width = var_get_width (v); value_init (&act->cut_point, width); value_init (&act->grp_val[0], width); value_init (&act->grp_val[1], width); if (width == 0) { act->cut_point.f = SYSMIS; act->grp_val[0].f = SYSMIS; act->grp_val[1].f = SYSMIS; } else { act->cut_point.short_string[0] = '\0'; act->grp_val[0].short_string[0] = '\0'; act->grp_val[1].short_string[0] = '\0'; } } act->grp_var = v; }
static int lua_function_proxy(lua_State*l) { assert(lua_islightuserdata(l, lua_upvalueindex(1))); function_data_t*data = (function_data_t*)lua_touserdata(l, lua_upvalueindex(1)); value_t*f = data->f; int i; log_dbg("[lua] lua calls function %s (%d parameters)", data->name, f->num_params); value_t*args = array_new(); int j = -f->num_params; for(i=0;i<f->num_params;i++) { value_t*a = lua_to_value(data->li, j++); if(a == NULL) { luaL_argerror(l, i+1, "invalid or missing value"); } array_append(args, a); } value_t*ret = f->call(f, args); value_destroy(args); push_value(l, ret); value_destroy(ret); return 1; }
static void csv_write_var (struct csv_writer *w, const struct csv_var *cv, const union value *value) { if (mv_is_value_missing (&cv->missing, value, MV_USER)) { union value missing; value_init (&missing, cv->width); value_set_missing (&missing, cv->width); csv_write_var__ (w, cv, &missing); value_destroy (&missing, cv->width); } else csv_write_var__ (w, cv, value); }
/* Callback */ void ini_cleanup_cb(const char *property, int property_len, int type, void *data, int length, void *custom_data) { struct value_obj *vo = NULL; TRACE_FLOW_ENTRY(); /* Banary items are the values */ if(type == COL_TYPE_BINARY) { vo = *((struct value_obj **)(data)); value_destroy(vo); } TRACE_FLOW_EXIT(); }
/* Configuration copy callback */ static int ini_copy_cb(struct collection_item *item, void *ext_data, int *skip) { int error = EOK; struct value_obj *vo = NULL; struct value_obj *new_vo = NULL; TRACE_FLOW_ENTRY(); ext_data = NULL; *skip = 0; /* Banary items are the values */ if(col_get_item_type(item) == COL_TYPE_BINARY) { vo = *((struct value_obj **)(col_get_item_data(item))); error = value_copy(vo, &new_vo); if (error) { TRACE_ERROR_NUMBER("Failed to copy value", error); return error; } error = col_modify_binary_item(item, NULL, &new_vo, sizeof(struct value_obj *)); if (error) { TRACE_ERROR_NUMBER("Failed to copy value", error); value_destroy(new_vo); return error; } } TRACE_FLOW_EXIT(); return error; }
/** Load an EFI application. * @param args Argument list. * @return Whether successful. */ static bool config_cmd_efi(value_list_t *args) { efi_loader_t *loader; status_t ret; if (args->count != 1 || args->values[0].type != VALUE_TYPE_STRING) { config_error("Invalid arguments"); return false; } loader = malloc(sizeof(*loader)); loader->args.type = VALUE_TYPE_STRING; split_cmdline(args->values[0].string, &loader->path, &loader->args.string); ret = fs_open(loader->path, NULL, FILE_TYPE_REGULAR, 0, &loader->handle); if (ret != STATUS_SUCCESS) { config_error("Error opening '%s': %pS", loader->path, ret); goto err_free; } loader->efi_path = convert_file_path(loader->handle, loader->path); if (!loader->efi_path) goto err_close; environ_set_loader(current_environ, &efi_loader_ops, loader); return true; err_close: fs_close(loader->handle); err_free: value_destroy(&loader->args); free(loader->path); free(loader); return false; }
static int zero_callback_max(struct value *ret_value, struct value *lhs, struct value_dict *arguments, size_t max, void *data) { size_t i; for (i = 0; i < max; ++i) { struct value element; if (value_init_element(&element, lhs, i) < 0) return -1; int zero = value_is_zero(&element, arguments); value_destroy(&element); if (zero) break; } struct arg_type_info *long_type = type_get_simple(ARGTYPE_LONG); value_init_detached(ret_value, NULL, long_type, 0); value_set_word(ret_value, i); return 0; }
void output_right(enum tof type, struct process *proc, struct library_symbol *libsym, struct timedelta *spent) { assert(! options.summary); struct prototype *func = lookup_symbol_prototype(proc, libsym); if (func == NULL) return; if (current_proc != NULL && (current_proc != proc || current_depth != proc->callstack_depth)) { fprintf(options.output, " <unfinished ...>\n"); current_proc = NULL; } if (current_proc != proc) { begin_of_line(proc, type == LT_TOF_FUNCTIONR, 1); #ifdef USE_DEMANGLE current_column += fprintf(options.output, "<... %s resumed> ", options.demangle ? my_demangle(libsym->name) : libsym->name); #else current_column += fprintf(options.output, "<... %s resumed> ", libsym->name); #endif } struct callstack_element *stel = &proc->callstack[proc->callstack_depth - 1]; struct fetch_context *context = stel->fetch_context; /* Fetch & enter into dictionary the retval first, so that * other values can use it in expressions. */ struct value retval; bool own_retval = false; if (context != NULL) { value_init(&retval, proc, NULL, func->return_info, 0); own_retval = true; if (fetch_retval(context, type, proc, func->return_info, &retval) < 0) value_set_type(&retval, NULL, 0); else if (stel->arguments != NULL && val_dict_push_named(stel->arguments, &retval, "retval", 0) == 0) own_retval = false; } if (stel->arguments != NULL) output_params(stel->arguments, stel->out.params_left, val_dict_count(stel->arguments), &stel->out.need_delim); current_column += fprintf(options.output, ") "); tabto(options.align - 1); fprintf(options.output, "= "); if (context != NULL && retval.type != NULL) { struct format_argument_data data = { &retval, stel->arguments }; format_argument_cb(options.output, &data); } if (own_retval) value_destroy(&retval); if (opt_T) { assert(spent != NULL); fprintf(options.output, " <%lu.%06d>", (unsigned long) spent->tm.tv_sec, (int) spent->tm.tv_usec); } fprintf(options.output, "\n"); #if defined(HAVE_LIBUNWIND) if (options.bt_depth > 0 && proc->unwind_priv != NULL && proc->unwind_as != NULL) { unw_cursor_t cursor; arch_addr_t ip, function_offset; struct library *lib = NULL; int unwind_depth = options.bt_depth; char fn_name[100]; const char *lib_name; size_t distance; /* Verify that we can safely cast arch_addr_t* to * unw_word_t*. */ (void)sizeof(char[1 - 2*(sizeof(unw_word_t) != sizeof(arch_addr_t))]); unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv); while (unwind_depth) { int rc = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip); if (rc < 0) { fprintf(options.output, " > Error: %s\n", unw_strerror(rc)); goto cont; } /* We are looking for the library with the base address * closest to the current ip. */ lib_name = "unmapped_area"; distance = (size_t) -1; lib = proc->libraries; while (lib != NULL) { /* N.B.: Assumes sizeof(size_t) == * sizeof(arch_addr_t). * Keyword: double cast. */ if ((ip >= lib->base) && ((size_t)(ip - lib->base) < distance)) { distance = ip - lib->base; lib_name = lib->pathname; } lib = lib->next; } rc = unw_get_proc_name(&cursor, fn_name, sizeof(fn_name), (unw_word_t *) &function_offset); if (rc == 0 || rc == -UNW_ENOMEM) fprintf(options.output, " > %s(%s+%p) [%p]\n", lib_name, fn_name, function_offset, ip); else fprintf(options.output, " > %s(??\?) [%p]\n", lib_name, ip); cont: if (unw_step(&cursor) <= 0) break; unwind_depth--; } fprintf(options.output, "\n"); } #endif /* defined(HAVE_LIBUNWIND) */ #if defined(HAVE_LIBDW) if (options.bt_depth > 0 && proc->leader->dwfl != NULL) { int frames = options.bt_depth; if (dwfl_getthread_frames(proc->leader->dwfl, proc->pid, frame_callback, &frames) < 0) { // Only print an error if we couldn't show anything. // Otherwise just show there might be more... if (frames == options.bt_depth) fprintf(stderr, "dwfl_getthread_frames tid %d: %s\n", proc->pid, dwfl_errmsg(-1)); else fprintf(options.output, " > [...]\n"); } fprintf(options.output, "\n"); } #endif /* defined(HAVE_LIBDW) */ current_proc = NULL; current_column = 0; }
/* Create a copy of the value */ int value_copy(struct value_obj *vo, struct value_obj **copy_vo) { int error = EOK; struct value_obj *new_vo = NULL; struct simplebuffer *oneline = NULL; TRACE_FLOW_ENTRY(); if ((!copy_vo) || (!vo)) { TRACE_ERROR_NUMBER("Invalid argument", EINVAL); return EINVAL; } /* Create buffer to hold the value */ error = simplebuffer_alloc(&oneline); if (error) { TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error); return error; } /* Put value into the buffer */ error = simplebuffer_add_str(oneline, (const char *)simplebuffer_get_buf(vo->unfolded), simplebuffer_get_len(vo->unfolded), INI_VALUE_BLOCK); if (error) { TRACE_ERROR_NUMBER("Failed to add string", error); simplebuffer_free(oneline); return error; } /* Acllocate new INI value structure */ new_vo = malloc(sizeof(struct value_obj)); if (!new_vo) { TRACE_ERROR_NUMBER("No memory", ENOMEM); simplebuffer_free(oneline); return ENOMEM; } new_vo->origin = vo->origin; new_vo->line = vo->line; new_vo->unfolded = oneline; new_vo->keylen = vo->keylen; new_vo->boundary = vo->boundary; new_vo->raw_lines = NULL; new_vo->raw_lengths = NULL; error = value_create_arrays(&(new_vo->raw_lines), &(new_vo->raw_lengths)); if (error) { TRACE_ERROR_NUMBER("Failed to fold", error); value_destroy(new_vo); return error; } /* Create arrays by folding the value */ error = value_fold(new_vo->unfolded, new_vo->keylen, new_vo->boundary, new_vo->raw_lines, new_vo->raw_lengths); if (error) { TRACE_ERROR_NUMBER("Failed to fold", error); value_destroy(new_vo); return error; } /* Copy comment */ if (vo->ic) { error = ini_comment_copy(vo->ic, &new_vo->ic); if (error) { TRACE_ERROR_NUMBER("Failed to copy comment", error); value_destroy(new_vo); return error; } } else new_vo->ic = NULL; *copy_vo = new_vo; TRACE_INFO_STRING("Orig value:", (const char *)simplebuffer_get_buf(vo->unfolded)); TRACE_INFO_STRING("Copy value:", (const char *)simplebuffer_get_buf(new_vo->unfolded)); TRACE_INFO_NUMBER("Orig value num lines:", ref_array_len(vo->raw_lengths)); TRACE_INFO_NUMBER("Copy value num lines:", ref_array_len(new_vo->raw_lengths)); TRACE_FLOW_EXIT(); return error; }
/* Create value object from string buffer */ int value_create_new(const char *strvalue, uint32_t length, uint32_t origin, uint32_t key_len, uint32_t boundary, struct ini_comment *ic, struct value_obj **vo) { int error = EOK; struct value_obj *new_vo = NULL; struct simplebuffer *oneline = NULL; TRACE_FLOW_ENTRY(); if ((!strvalue) || (!vo)) { TRACE_ERROR_NUMBER("Invalid argument", EINVAL); return EINVAL; } /* Create buffer to hold the value */ error = simplebuffer_alloc(&oneline); if (error) { TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error); return error; } /* Put value into the buffer */ error = simplebuffer_add_str(oneline, strvalue, length, INI_VALUE_BLOCK); if (error) { TRACE_ERROR_NUMBER("Failed to add string", error); simplebuffer_free(oneline); return error; } /* Acllocate new INI value structure */ new_vo = malloc(sizeof(struct value_obj)); if (!new_vo) { TRACE_ERROR_NUMBER("No memory", ENOMEM); simplebuffer_free(oneline); return ENOMEM; } new_vo->origin = origin; /* Line is not known in this case */ new_vo->line = 0; new_vo->ic = ic; new_vo->unfolded = oneline; new_vo->keylen = key_len; new_vo->boundary = boundary; new_vo->raw_lines = NULL; new_vo->raw_lengths = NULL; error = value_create_arrays(&(new_vo->raw_lines), &(new_vo->raw_lengths)); if (error) { TRACE_ERROR_NUMBER("Failed to fold", error); value_destroy(new_vo); return error; } /* Create arrays by folding the value */ error = value_fold(new_vo->unfolded, new_vo->keylen, new_vo->boundary, new_vo->raw_lines, new_vo->raw_lengths); if (error) { TRACE_ERROR_NUMBER("Failed to fold", error); value_destroy(new_vo); return error; } *vo = new_vo; TRACE_FLOW_EXIT(); return error; }
/* Callback which occurs when the OK button is clicked */ static void missing_val_dialog_accept (GtkWidget *w, gpointer data) { struct missing_val_dialog *dialog = data; if ( gtk_toggle_button_get_active (dialog->button_discrete)) { gint nvals = 0; gint badvals = 0; gint i; mv_clear(&dialog->mvl); for(i = 0 ; i < 3 ; ++i ) { gchar *text = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->mv[i]))); union value v; if ( !text || strlen (g_strstrip (text)) == 0 ) { g_free (text); continue; } if ( text_to_value (text, dialog->pv, &v)) { nvals++; mv_add_value (&dialog->mvl, &v); } else badvals++; g_free (text); value_destroy (&v, var_get_width (dialog->pv)); } if ( nvals == 0 || badvals > 0 ) { err_dialog (_("Incorrect value for variable type"), GTK_WINDOW (dialog->window)); return ; } } if (gtk_toggle_button_get_active (dialog->button_range)) { gchar *discrete_text ; union value low_val ; union value high_val; const gchar *low_text = gtk_entry_get_text (GTK_ENTRY (dialog->low)); const gchar *high_text = gtk_entry_get_text (GTK_ENTRY (dialog->high)); if ( text_to_value (low_text, dialog->pv, &low_val) && text_to_value (high_text, dialog->pv, &high_val)) { if ( low_val.f > high_val.f ) { err_dialog (_("Incorrect range specification"), GTK_WINDOW (dialog->window)); value_destroy (&low_val, var_get_width (dialog->pv)); value_destroy (&high_val, var_get_width (dialog->pv)); return ; } } else { err_dialog (_("Incorrect range specification"), GTK_WINDOW (dialog->window)); value_destroy (&low_val, var_get_width (dialog->pv)); value_destroy (&high_val, var_get_width (dialog->pv)); return; } discrete_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->discrete))); mv_clear (&dialog->mvl); mv_add_range (&dialog->mvl, low_val.f, high_val.f); value_destroy (&low_val, var_get_width (dialog->pv)); value_destroy (&high_val, var_get_width (dialog->pv)); if ( discrete_text && strlen (g_strstrip (discrete_text)) > 0 ) { union value discrete_val; if ( !text_to_value (discrete_text, dialog->pv, &discrete_val)) { err_dialog (_("Incorrect value for variable type"), GTK_WINDOW (dialog->window) ); g_free (discrete_text); value_destroy (&discrete_val, var_get_width (dialog->pv)); return; } mv_add_value (&dialog->mvl, &discrete_val); value_destroy (&discrete_val, var_get_width (dialog->pv)); } g_free (discrete_text); } if (gtk_toggle_button_get_active (dialog->button_none)) mv_clear (&dialog->mvl); var_set_missing_values (dialog->pv, &dialog->mvl); gtk_widget_hide (dialog->window); }
/* Complete value processing */ static int complete_value_processing(struct parser_obj *po) { int error = EOK; int error2 = EOK; struct value_obj *vo = NULL; struct value_obj *vo_old = NULL; unsigned insertmode; uint32_t mergemode; int suppress = 0; int doinsert = 0; struct collection_item *item = NULL; struct collection_item *section = NULL; int merging = 0; TRACE_FLOW_ENTRY(); if (po->merge_sec) { TRACE_INFO_STRING("Processing value in merge mode", ""); section = po->merge_sec; merging = 1; } else if(!(po->sec)) { TRACE_INFO_STRING("Creating default section", ""); /* If there is not open section create a default one */ error = col_create_collection(&po->sec, INI_DEFAULT_SECTION, COL_CLASS_INI_SECTION); if (error) { TRACE_ERROR_NUMBER("Failed to create default section", error); return error; } section = po->sec; } else { TRACE_INFO_STRING("Processing value in normal mode", ""); section = po->sec; } if (merging) { TRACE_INFO_STRING("Using merge key:", po->merge_key); vo = po->merge_vo; /* We are adding to the merge section so use MV2S flags. * But flags are done in such a way that deviding MV2S by MV1S mask * will translate MV2S flags into MV1S so we can use * MV1S constants. */ TRACE_INFO_NUMBER("Collisions flags:", po->collision_flags); mergemode = (po->collision_flags & INI_MV2S_MASK) / INI_MV1S_MASK; } else { /* Construct value object from what we have */ error = value_create_from_refarray(po->raw_lines, po->raw_lengths, po->keylinenum, INI_VALUE_READ, po->key_len, po->boundary, po->ic, &vo); if (error) { TRACE_ERROR_NUMBER("Failed to create value object", error); return error; } /* Forget about the arrays. They are now owned by the value object */ po->ic = NULL; po->raw_lines = NULL; po->raw_lengths = NULL; mergemode = po->collision_flags & INI_MV1S_MASK; } switch (mergemode) { case INI_MV1S_ERROR: insertmode = COL_INSERT_DUPERROR; doinsert = 1; break; case INI_MV1S_PRESERVE: insertmode = COL_INSERT_DUPERROR; doinsert = 1; suppress = 1; break; case INI_MV1S_ALLOW: insertmode = COL_INSERT_NOCHECK; doinsert = 1; break; case INI_MV1S_OVERWRITE: /* Special handling */ case INI_MV1S_DETECT: default: break; } /* Do not insert but search for dups first */ if (!doinsert) { TRACE_INFO_STRING("Overwrite mode. Looking for:", (char *)(merging ? po->merge_key : po->key)); error = col_get_item(section, merging ? po->merge_key : po->key, COL_TYPE_BINARY, COL_TRAVERSE_DEFAULT, &item); if (error) { TRACE_ERROR_NUMBER("Failed searching for dup", error); value_destroy(vo); return error; } /* Check if there is a dup */ if (item) { /* Check if we are in the detect mode */ if (mergemode == INI_MV1S_DETECT) { po->merge_error = EEXIST; /* There is a dup - inform user about it and continue */ error = save_error(po->el, merging ? po->seclinenum : po->keylinenum, merging ? ERR_DUPKEYSEC : ERR_DUPKEY, ERROR_TXT); if (error) { TRACE_ERROR_NUMBER("Failed to save error", error); value_destroy(vo); return error; } doinsert = 1; insertmode = COL_INSERT_NOCHECK; } else { /* Dup exists - update it */ vo_old = *((struct value_obj **)(col_get_item_data(item))); error = col_modify_binary_item(item, NULL, &vo, sizeof(struct value_obj *)); if (error) { TRACE_ERROR_NUMBER("Failed updating the value", error); value_destroy(vo); return error; } /* If we failed to update it is better to leak then crash, * so destroy original value only on the successful update. */ value_destroy(vo_old); } } else { /* No dup found so we can insert with no check */ doinsert = 1; insertmode = COL_INSERT_NOCHECK; } } if (doinsert) { /* Add value to collection */ error = col_insert_binary_property(section, NULL, COL_DSP_END, NULL, 0, insertmode, merging ? po->merge_key : po->key, &vo, sizeof(struct value_obj *)); if (error) { value_destroy(vo); if ((suppress) && (error == EEXIST)) { TRACE_INFO_STRING("Preseved exisitng value", (char *)(merging ? po->merge_key : po->key)); } else { /* Check if this is a critical error or not */ if ((mergemode == INI_MV1S_ERROR) && (error == EEXIST)) { TRACE_ERROR_NUMBER("Failed to add value object " "to the section", error); error2 = save_error(po->el, merging ? po->seclinenum : po->keylinenum, merging ? ERR_DUPKEYSEC : ERR_DUPKEY, ERROR_TXT); if (error2) { TRACE_ERROR_NUMBER("Failed to save error", error2); return error2; } return error; } else { TRACE_ERROR_NUMBER("Failed to add value object" " to the section", error); return error; } } } } if (!merging) { free(po->key); po->key = NULL; po->key_len = 0; } TRACE_FLOW_EXIT(); return EOK; }
/* Merge contents of the section */ static int merge_section(struct parser_obj *po) { int error = EOK; struct collection_item *item = NULL; struct value_obj *vo = NULL; int work_to_do = 1; const char *key; TRACE_FLOW_ENTRY(); do { TRACE_INFO_STRING("Top of the merge loop", ""); item = NULL; error = col_extract_item_from_current(po->sec, COL_DSP_FRONT, NULL, 0, COL_TYPE_ANY, &item); if ((error) && (error != ENOENT)) { TRACE_ERROR_NUMBER("Failed to extract item.", error); return error; } if (item) { TRACE_INFO_STRING("Item found:", col_get_item_property(item, NULL)); if (strncmp(col_get_item_property(item, NULL), INI_SECTION_KEY, 1) == 0) { /* Just ignore the first item */ vo = *((struct value_obj **)(col_get_item_data(item))); value_destroy(vo); col_delete_item(item); continue; } po->merge_vo = *((struct value_obj **)(col_get_item_data(item))); key = col_get_item_property(item, NULL); /* To be able to use po->merge_key in the loop * we have to overcome constraints imposed by * the "const" declaration. */ memcpy(&(po->merge_key), &key, sizeof(char *)); /* Use the value processing function to inser the value */ error = complete_value_processing(po); /* In case of error value is already cleaned */ po->merge_vo = NULL; po->merge_key = NULL; col_delete_item(item); /* Now we can check the error */ if (error) { TRACE_ERROR_NUMBER("Failed to merge item.", error); return error; } } else { TRACE_INFO_STRING("No more items:", ""); work_to_do = 0; } } while (work_to_do); /* If we reached this place the incoming section is empty. * but just to be safe clean with callback. */ col_destroy_collection_with_cb(po->sec, ini_cleanup_cb, NULL); po->sec = NULL; TRACE_FLOW_EXIT(); return EOK; }
/* Clean all items in the section */ int empty_section(struct collection_item *sec) { int error = EOK; struct collection_item *item = NULL; struct collection_item *save_item = NULL; struct value_obj *vo = NULL; int work_to_do = 1; TRACE_FLOW_ENTRY(); do { item = NULL; error = col_extract_item_from_current(sec, COL_DSP_FRONT, NULL, 0, COL_TYPE_ANY, &item); if ((error) && (error != ENOENT)) { TRACE_ERROR_NUMBER("Failed to extract item.", error); return error; } if (item) { TRACE_INFO_STRING("Item found:", col_get_item_property(item, NULL)); if (strncmp(col_get_item_property(item, NULL), INI_SECTION_KEY, 1) == 0) { /* Just ignore the first item */ save_item = item; continue; } vo = *((struct value_obj **)(col_get_item_data(item))); value_destroy(vo); col_delete_item(item); } else { TRACE_INFO_STRING("No more items:", ""); /* Restore saved item */ error = col_insert_item(sec, NULL, save_item, COL_DSP_END, NULL, 0, COL_INSERT_NOCHECK); if (error) { TRACE_ERROR_NUMBER("Failed to restore item.", error); return error; } work_to_do = 0; } } while (work_to_do); TRACE_FLOW_EXIT(); return EOK; }