/*** map * Mapping functional form. Accepts a single function argument. Input to the * form should always be in the form of a list, and the return value will be * the result of applying the argument function to each element in the list. * * map{ f } : < x, y, z > = < f : x, f : y, f : z > */ struct value *map(struct list *args, struct value *in) { struct value *out = NULL; struct function *f = list_get(args, 0); struct list *l = NULL; struct cursor *c; // First ensure valid input if(args->count != 1 || in->type != SEQ_VAL) { value_delete(in); return value_new(); } // Otherwise create an output list by applying f to each element of in out = value_new(); out->type = SEQ_VAL; out->data.seq_val = list_new(); l = in->data.seq_val; for(c = cursor_new_front(l); cursor_valid(c); cursor_next(c)) list_push_back(out->data.seq_val, function_exec(f, value_copy(cursor_get(c)))); value_delete(in); cursor_delete(c); return out; }
void *context_eval(engine_context *context, char *script) { zval str; VALUE_SET_STRING(&str, script); // Compile script value. uint32_t compiler_options = CG(compiler_options); CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL; zend_op_array *op = zend_compile_string(&str, "gophp-engine"); CG(compiler_options) = compiler_options; zval_dtor(&str); // Return error if script failed to compile. if (!op) { errno = 1; return NULL; } // Attempt to execute compiled string. zval tmp; CONTEXT_EXECUTE(op, &tmp); // Allocate result value and copy temporary execution result in. zval *result = malloc(sizeof(zval)); value_copy(result, &tmp); errno = 0; return result; }
/*** if * Conditional form. Accepts exactly three arguments. First feeds its input * to the first argument. If the result is boolean True, it feeds the input to * its second argument, if False then it feeds it to its third argument, * otherwise it just returns Bottom. * * if{ f, g, h } : x = if f : x then g : x else h : x */ struct value *iff(struct list *args, struct value *in) { struct value *test = value_copy(in); struct value *out = NULL; // Checking for correct number of arguments if(args->count != 3) { value_delete(test); value_delete(in); return value_new(); } // Testing input with first argument test = function_exec(list_get(args, 0), test); if(test->type == BOOL_VAL) { if(test->data.bool_val) { value_delete(test); return function_exec(list_get(args, 1), in); } else { value_delete(test); return function_exec(list_get(args, 2), in); } } else { value_delete(in); return value_new(); } }
/*** reduce * Reducing functional form. Accepts a single function argument. Expects * input in the form of a list, return value is the result of first applying * the argument function to a pair formed from the first two elements of the * input list, then forming a new pair from that result and the next * right-most element, and so on until the list is exhausted. * * reduce{ f } : < x, y, z > = f : < f : < x, y>, z > */ struct value *reduce(struct list *args, struct value *in) { struct value *out = value_new(); struct value *v = NULL; struct function *f = list_get(args, 0); int i = 0; // Check for valid input if (args->count != 1 || in->type != SEQ_VAL || in->data.seq_val->count < 2) { value_delete(in); return out; } // Setting up initial pair out->type = SEQ_VAL; out->data.seq_val = list_new(); list_push_back(out->data.seq_val, value_copy(list_get(in->data.seq_val, 0))); list_push_back(out->data.seq_val, value_copy(list_get(in->data.seq_val, 1))); // Pairing up elements and feeding them to f for (i = 2; i <= in->data.seq_val->count; i++) { out = function_exec(f, out); if (i < in->data.seq_val->count) { v = value_new(); v->type = SEQ_VAL; v->data.seq_val = list_new(); list_push_back(v->data.seq_val, out); list_push_back(v->data.seq_val, value_copy(list_get(in->data.seq_val, i))); out = v; } } value_delete(in); return out; }
/* リストの末尾から要素を取り出す */ value* list_pop(value* list) { if (!list->size) { fprintf(stderr, "List has no elements.\n"); return NULL; } value* res = list_ref(list, list_last(list)); if (res) { res = value_copy(res); } list_resize(list, list_last(list)); return res; }
static Value * identifier(const Ast *expr) { Memory *m = memspace_load(current_memspace, expr->symbol); assert(m != NULL); assert(m->value != NULL); Value *rval = value_new(); value_copy(rval, m->value); return rval; }
struct chain * add_to_chain(struct chain *c, struct value *v) { struct chain *n; n = malloc(sizeof(struct chain)); n->next = NULL; value_copy(&n->value, v); if (c != NULL) { c->next = n; } return n; }
/* Find a pretty-printer object for the varobj module. Returns a new reference to the object if successful; returns NULL if not. VALUE is the value for which a printer tests to determine if it can pretty-print the value. */ PyObject * gdbpy_get_varobj_pretty_printer (struct value *value) { PyObject *val_obj; PyObject *pretty_printer = NULL; TRY { value = value_copy (value); } CATCH (except, RETURN_MASK_ALL) { GDB_PY_HANDLE_EXCEPTION (except); }
/** Copy a value list. * @param source Source list. * @return Pointer to destination list. */ value_list_t *value_list_copy(const value_list_t *source) { value_list_t *dest = malloc(sizeof(*dest)); dest->count = source->count; if (source->count) { dest->values = malloc(sizeof(*dest->values) * source->count); for (size_t i = 0; i < source->count; i++) value_copy(&source->values[i], &dest->values[i]); } else { dest->values = NULL; } return dest; }
/* リストの先頭から要素を取り出す */ value* list_shift(value* list) { if (!list->size) { fprintf(stderr, "List has no elements.\n"); return NULL; } value* res = list_ref(list, 0); if (res) { res = value_copy(res); } for (int i=0; i<list->size - 1; i++) { list->a[i] = list->a[i + 1]; } list_resize(list, list_last(list)); return res; }
static Value * assignment(const Ast *ast) { Ast *id = ast->child; Ast *expr = ast->child->next; Memory *m = memspace_load(current_memspace, id->symbol); assert(m != NULL); assert(m->value != NULL); Value *rval = eval(expr); value_copy(m->value, rval); return rval; }
TypedValue CharType::coerceValue(const TypedValue &original_value, const Type &original_type) const { DCHECK(isCoercibleFrom(original_type)) << "Can't coerce value of Type " << original_type.getName() << " to Type " << getName(); if (original_value.isNull()) { return makeNullValue(); } const void *original_data = original_value.getOutOfLineData(); const std::size_t original_data_size = original_value.getDataSize(); // VARCHAR always has a null-terminator. CHAR(X) has a null-terminator when // string's length is less than X. const bool null_terminated = (original_type.getTypeID() == kVarChar) || (original_data_size < original_type.maximumByteLength()) || (std::memchr(original_data, '\0', original_data_size) != nullptr); if (original_data_size <= length_) { if (null_terminated || (original_data_size == length_)) { TypedValue value_copy(original_value); value_copy.markType(kChar); return value_copy; } else { // Need to make a new NULL-terminated copy of the string. char *null_terminated_str = static_cast<char*>(std::malloc(original_data_size + 1)); std::memcpy(null_terminated_str, original_data, original_data_size); null_terminated_str[original_data_size] = '\0'; return TypedValue::CreateWithOwnedData(kChar, null_terminated_str, original_data_size + 1); } } else { // Need to truncate. if (original_value.ownsOutOfLineData()) { char *truncated_str = static_cast<char*>(std::malloc(length_)); std::memcpy(truncated_str, original_data, length_); return TypedValue::CreateWithOwnedData(kChar, truncated_str, length_); } else { // Original is a reference, so we will just make a shorter reference. return TypedValue(kChar, original_data, length_); } } }
/*** construct * Sequence construction. Feeds its input to each of its argument functions, * and generate a sequence where each element is the output of one of the * argument functions. * * construct{ f, g } : x = < f : x, g : x > */ struct value *construct(struct list *args, struct value *in) { struct value *out = value_new(); struct cursor *c = NULL; out->type = SEQ_VAL; out->data.seq_val = list_new(); for(c = cursor_new_front(args); cursor_valid(c); cursor_next(c)) { list_push_back(out->data.seq_val, function_exec(cursor_get(c), value_copy(in))); } value_delete(in); cursor_delete(c); return out; }
/* Copies the data from FILE's case into output case OUTPUT, skipping values that are missing or all spaces. If FILE has an IN variable, then it is set to 1 in OUTPUT. */ static void apply_nonmissing_case (const struct comb_file *file, struct ccase *output) { size_t i; for (i = 0; i < subcase_get_n_fields (&file->src); i++) { const struct subcase_field *src_field = &file->src.fields[i]; const struct subcase_field *dst_field = &file->dst.fields[i]; const union value *src_value = case_data_idx (file->data, src_field->case_index); int width = src_field->width; if (!mv_is_value_missing (file->mv[i], src_value, MV_ANY) && !(width > 0 && value_is_spaces (src_value, width))) value_copy (case_data_rw_idx (output, dst_field->case_index), src_value, width); } mark_file_used (file, output); }
/** * Checks the extension of a filename * @param value :: the filename to check * @return flag that true if the extension matches in the filename */ bool FileValidator::endswith(const std::string &value) const { if (m_extensions.empty()) // automatically match a lack of extensions return true; if ((m_extensions.size() == 1) && (m_extensions.begin()->empty())) return true; // create a lowercase copy of the filename std::string value_copy(value); std::transform(value_copy.begin(), value_copy.end(), value_copy.begin(), tolower); // check for the ending for (std::set<std::string>::const_iterator it = m_extensions.begin(); it != m_extensions.end(); ++it) { if (has_ending(value, *it)) // original case return true; if (has_ending(value_copy, *it)) // lower case return true; } return false; }
/* * Generate a reference to a label into the tuple, for instance as the * immediate argument of a branch instruction. If the label parameter * is NULL, this will generate and return a forward reference which * should be resolved by subsequently passing it to gen_define_label(). */ void gen_gen_label_ref(struct value *gen, struct value *gen_label) { struct value *bp; struct value next; int global_pos; assert(gen_label != NULL); if (value_is_null(gen_label)) { /* Not yet allocated, so allocate a new undefined one. */ gen_label_new(gen_label); } global_pos = value_tuple_fetch_integer(gen_label, GEN_LABEL_GLOBAL_POS); if (global_pos != 0) { /* Already defined, so just use it. */ gen_integer(gen, global_pos); return; } /* * The label is newly allocated, or at least has not been defined * yet. So, we remember that we will need to backpatch here in the * future (by adding an entry to the label's backpatch list) and, * for now, generate a NULL in its slot. */ value_copy(&next, value_tuple_fetch(gen_label, GEN_LABEL_NEXT)); bp = value_tuple_fetch(gen_label, GEN_LABEL_NEXT); gen_label_new(bp); value_tuple_store(bp, GEN_LABEL_TUPLE, value_tuple_fetch(gen, GEN_CURRENT_TUPLE)); value_tuple_store(bp, GEN_LABEL_LOCAL_POS, value_tuple_fetch(gen, GEN_LOCAL_POS)); value_tuple_store(bp, GEN_LABEL_GLOBAL_POS, value_tuple_fetch(gen, GEN_GLOBAL_POS)); value_tuple_store(bp, GEN_LABEL_NEXT, &next); gen_value(gen, &VNULL); }
/* 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; }
/* charCodeAt */ static int strpto_charCodeAt(PSTATE *ps, Value *args, Value *_this, Value *ret, int asc) { if (asc) die("Execute String.prototype.charCodeAt as constructor\n"); Value target = { 0 }; value_copy(target, *_this); value_tostring(&target); int slen = unistrlen(target.d.str); int pos = 0; Value *vpos; if ((vpos = value_object_lookup_array(args, 0, NULL))) { value_toint32(vpos); pos = (int)vpos->d.num; } if (pos < 0 || pos >= slen) { value_make_number(*ret, ieee_makenan()); } else { value_make_number(*ret, target.d.str[pos]); } value_erase(target); return 0; }
int c_value_print (struct value *val, struct ui_file *stream, int format, enum val_prettyprint pretty) { struct type *type, *real_type; int full, top, using_enc; /* If it is a pointer, indicate what it points to. Print type also if it is a reference. C++: if it is a member pointer, we will take care of that when we print it. */ type = check_typedef (value_type (val)); if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF) { /* Hack: remove (char *) for char strings. Their type is indicated by the quoted string anyway. */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_NAME (type) == NULL && TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0) { /* Print nothing */ } else if (objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) { if (TYPE_CODE(type) == TYPE_CODE_REF) { /* Copy value, change to pointer, so we don't get an * error about a non-pointer type in value_rtti_target_type */ struct value *temparg; temparg=value_copy(val); deprecated_set_value_type (temparg, lookup_pointer_type (TYPE_TARGET_TYPE(type))); val=temparg; } /* Pointer to class, check real type of object */ fprintf_filtered (stream, "("); real_type = value_rtti_target_type (val, &full, &top, &using_enc); if (real_type) { /* RTTI entry found */ if (TYPE_CODE (type) == TYPE_CODE_PTR) { /* create a pointer type pointing to the real type */ type = lookup_pointer_type (real_type); } else { /* create a reference type referencing the real type */ type = lookup_reference_type (real_type); } /* JYG: Need to adjust pointer value. */ /* NOTE: cagney/2005-01-02: THIS IS BOGUS. */ value_contents_writeable (val)[0] -= top; /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); } else { /* normal case */ fprintf_filtered (stream, "("); type_print (value_type (val), "", stream, -1); fprintf_filtered (stream, ") "); } } /* APPLE LOCAL begin variable initialized status. */ if (value_var_status (val) == 0) fprintf_filtered (stream, " [uninitialized] "); /* APPLE LOCAL end variable initialized status. */ if (objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS)) { /* Attempt to determine real type of object */ real_type = value_rtti_type (val, &full, &top, &using_enc); if (real_type) { /* We have RTTI information, so use it */ val = value_full_object (val, real_type, full, top, using_enc); fprintf_filtered (stream, "(%s%s) ", TYPE_NAME (real_type), full ? "" : _(" [incomplete object]")); /* Print out object: enclosing type is same as real_type if full */ return val_print (value_enclosing_type (val), value_contents_all (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } else if (type != check_typedef (value_enclosing_type (val))) { /* No RTTI information, so let's do our best */ fprintf_filtered (stream, "(%s ?) ", TYPE_NAME (value_enclosing_type (val))); return val_print (value_enclosing_type (val), value_contents_all (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); } /* Otherwise, we end up at the return outside this "if" */ } real_type = get_closure_dynamic_type (val); if (real_type) type = real_type; return val_print (type, value_contents_all (val), value_embedded_offset (val), VALUE_ADDRESS (val) + value_offset (val), stream, format, 1, 0, pretty); }
/* Writes an aggregated record to OUTPUT. */ static void dump_aggregate_info (const struct agr_proc *agr, struct casewriter *output, const struct ccase *break_case) { struct ccase *c = case_create (dict_get_proto (agr->dict)); if ( agr->add_variables) { case_copy (c, 0, break_case, 0, dict_get_var_cnt (agr->src_dict)); } else { int value_idx = 0; int i; for (i = 0; i < agr->break_var_cnt; i++) { const struct variable *v = agr->break_vars[i]; value_copy (case_data_rw_idx (c, value_idx), case_data (break_case, v), var_get_width (v)); value_idx++; } } { struct agr_var *i; for (i = agr->agr_vars; i; i = i->next) { union value *v = case_data_rw (c, i->dest); int width = var_get_width (i->dest); if (agr->missing == COLUMNWISE && i->saw_missing && (i->function & FUNC) != N && (i->function & FUNC) != NU && (i->function & FUNC) != NMISS && (i->function & FUNC) != NUMISS) { value_set_missing (v, width); casewriter_destroy (i->writer); continue; } switch (i->function) { case SUM: v->f = i->int1 ? i->dbl[0] : SYSMIS; break; case MEAN: v->f = i->dbl[1] != 0.0 ? i->dbl[0] / i->dbl[1] : SYSMIS; break; case MEDIAN: { if ( i->writer) { struct percentile *median = percentile_create (0.5, i->cc); struct order_stats *os = &median->parent; struct casereader *sorted_reader = casewriter_make_reader (i->writer); i->writer = NULL; order_stats_accumulate (&os, 1, sorted_reader, i->weight, i->subject, i->exclude); i->dbl[0] = percentile_calculate (median, PC_HAVERAGE); statistic_destroy (&median->parent.parent); } v->f = i->dbl[0]; } break; case SD: { double variance; /* FIXME: we should use two passes. */ moments1_calculate (i->moments, NULL, NULL, &variance, NULL, NULL); if (variance != SYSMIS) v->f = sqrt (variance); else v->f = SYSMIS; } break; case MAX: case MIN: v->f = i->int1 ? i->dbl[0] : SYSMIS; break; case MAX | FSTRING: case MIN | FSTRING: if (i->int1) memcpy (value_str_rw (v, width), i->string, width); else value_set_missing (v, width); break; case FGT: case FGT | FSTRING: case FLT: case FLT | FSTRING: case FIN: case FIN | FSTRING: case FOUT: case FOUT | FSTRING: v->f = i->dbl[1] ? i->dbl[0] / i->dbl[1] : SYSMIS; break; case PGT: case PGT | FSTRING: case PLT: case PLT | FSTRING: case PIN: case PIN | FSTRING: case POUT: case POUT | FSTRING: v->f = i->dbl[1] ? i->dbl[0] / i->dbl[1] * 100.0 : SYSMIS; break; case N: case N | FSTRING: v->f = i->dbl[0]; break; case NU: case NU | FSTRING: v->f = i->int1; break; case FIRST: case LAST: v->f = i->int1 ? i->dbl[0] : SYSMIS; break; case FIRST | FSTRING: case LAST | FSTRING: if (i->int1) memcpy (value_str_rw (v, width), i->string, width); else value_set_missing (v, width); break; case NMISS: case NMISS | FSTRING: v->f = i->dbl[0]; break; case NUMISS: case NUMISS | FSTRING: v->f = i->int1; break; default: NOT_REACHED (); } } } casewriter_write (output, c); }
/** * Substitute variable references in a value. * * Substitutes variable references in a value (entirely replaces reference * values, and substitutes variables within strings). If the value is a list, * will recurse onto the values contained within the list. If an error occurs * while substituting variables, the error will be raised with config_error() * and the function will return false. For strings/references, if an error * occurs, the value will not be changed. * * @param value Value to substitute in. * @param env Environment to take variables from. * * @return Whether variables were successfully substituted. */ bool value_substitute(value_t *value, environ_t *env) { const value_t *target; char *str; size_t i, start; switch (value->type) { case VALUE_TYPE_REFERENCE: /* Non-string variable reference, replace the whole value. */ target = environ_lookup(env, value->string); if (!target) { config_error("Variable '%s' not found", value->string); return false; } free(value->string); value_copy(target, value); break; case VALUE_TYPE_STRING: /* Search for in-string variable references, which we substitute in the * string for a string representation of the variable. */ str = strdup(value->string); i = 0; start = 0; while (str[i]) { if (start) { if (isalnum(str[i]) || str[i] == '_') { i++; } else if (str[i] == '}') { const char *name; char *subst; size_t prefix_len, var_len, len; str[start - 2] = 0; str[i] = 0; /* We have a whole reference. */ name = &str[start]; target = environ_lookup(env, name); if (!target) { config_error("Variable '%s' not found", name); free(str); return false; } /* Stringify the target into the temporary buffer. */ switch (target->type) { case VALUE_TYPE_INTEGER: snprintf(temp_buf, TEMP_BUF_LEN, "%llu", target->integer); break; case VALUE_TYPE_BOOLEAN: snprintf(temp_buf, TEMP_BUF_LEN, (target->boolean) ? "true" : "false"); break; case VALUE_TYPE_STRING: snprintf(temp_buf, TEMP_BUF_LEN, "%s", target->string); break; default: config_error("Variable '%s' cannot be converted to string", name); free(str); return false; } /* Now allocate a new string. The start and end characters * of the reference have been replaced with null terminators * effectively splitting up the string into 3 parts. */ prefix_len = strlen(str); var_len = strlen(temp_buf); len = prefix_len + var_len + strlen(&str[i + 1]) + 1; subst = malloc(len); snprintf(subst, len, "%s%s%s", str, temp_buf, &str[i + 1]); /* Replace the string and continue after the substituted * portion. */ free(str); str = subst; i = prefix_len + var_len; start = 0; } else { start = 0; i++; } } else { if (str[i] == '$' && str[i + 1] == '{') { i += 2; start = i; } else { i++; } } } free(value->string); value->string = str; break; case VALUE_TYPE_LIST: for (i = 0; i < value->list->count; i++) { if (!value_substitute(&value->list->values[i], env)) return false; } break; default: break; } return true; }
int eval(PSTATE *ps, OpCodes *opcodes, ScopeChain *scope, Value *currentScope, /* scope chain */ Value *_this, Value *vret) { int context_id = ps->_context_id++; OpCode *ip = &opcodes->codes[0]; OpCode *end = &opcodes->codes[opcodes->code_len]; TryList *trylist = NULL; if (currentScope->vt != VT_OBJECT) { bug("Eval: current scope is not a object\n"); } while(ip < end) { #ifdef DEBUG int i; printf("STACK%d: ", sp); for (i = 0; i < sp; ++i) { printf("%s ", vprint(&stack[i])); } printf("\tthis: %s ", vprint(_this)); TryList *tlt = trylist; for (i = 0; tlt; tlt = tlt->next) i++; printf("TL: %d, excpt: %s\n", i, vprint(&ps->last_exception)); code_decode(ip, ip - opcodes->codes); #endif switch(ip->op) { case OP_NOP: case OP_LASTOP: break; case OP_PUSHNUM: value_make_number(stack[sp], (*((double *)ip->data))); sp++; break; case OP_PUSHSTR: value_make_string(stack[sp], unistrdup(ip->data)); sp++; break; case OP_PUSHVAR: { FastVar *n = ip->data; Value *v = NULL; if (n->context_id == context_id) { v = n->var.lval; } else { unichar *varname = n->var.varname; v = value_object_lookup(currentScope, (ObjKey *)varname, NULL); if (!v) v = scope_chain_object_lookup(scope, (ObjKey *)varname); if (!v) { /* add to global scope */ Value *global_scope = scope->chains_cnt > 0 ? scope->chains[0]:currentScope; Value key; value_make_string(key, varname); /* varname is not dupped, do not erase*/ Value val; value_make_undef(val); v = value_object_key_assign(global_scope, &key, &val, OM_DONTEMU); /* key assign dup key and insert into object, so release ourself */ } n->context_id = context_id; n->var.lval = v; } stack[sp].vt = VT_VARIABLE; stack[sp].d.lval = v; sp++; break; } case OP_PUSHUND: value_make_undef(stack[sp]); sp++; break; case OP_PUSHBOO: value_make_bool(stack[sp], (int)ip->data); sp++; break; case OP_PUSHFUN: { FuncObj *fo = funcobj_new((Func *)ip->data); fo->scope = scope_chain_dup_next(scope, currentScope); Object *obj = object_new(); obj->ot = OT_FUNCTION; obj->d.fobj = fo; obj->__proto__ = Function_prototype; Value *fun_prototype = value_object_utils_new_object(); fun_prototype->d.obj->__proto__ = Object_prototype; value_make_object(stack[sp], obj); value_object_utils_insert(&stack[sp], PROTOTYPE.unistr, fun_prototype, 0, 1, 0); /* todo: make own prototype and prototype.constructor */ sp++; break; } case OP_PUSHREG: { Object *obj = object_new(); obj->ot = OT_REGEXP; obj->d.robj = (regex_t *)ip->data; obj->__proto__ = RegExp_prototype; value_make_object(stack[sp], obj); sp++; break; } case OP_PUSHARG: value_copy(stack[sp], *currentScope); sp++; break; case OP_PUSHTHS: value_copy(stack[sp], *_this); sp++; break; case OP_PUSHTOP: value_copy(stack[sp], TOP); sp++; break; case OP_UNREF: topeval1(); break; case OP_PUSHTOP2: value_copy(stack[sp], TOQ); value_copy(stack[sp+1], TOP); sp += 2; break; case OP_CHTHIS: { int t = sp - 2; if (ip->data) { value_erase(obj_this[t]); value_copy(obj_this[t], TOQ); if (obj_this[t].vt == VT_VARIABLE) { Value *v = obj_this[t].d.lval; value_copy(obj_this[t], *v); } value_toobject(&obj_this[t]); } break; } case OP_LOCAL: { ObjKey *strkey = objkey_new((const unichar *)ip->data, OM_DONTEMU); value_object_insert(currentScope, strkey, value_new()); /* make all FastVar to be relocated */ context_id = ps->_context_id++; break; } case OP_POP: pop_n(ip->data); break; case OP_NEG: topeval1(); value_tonumber(&TOP); TOP.d.num = -(TOP.d.num); break; case OP_POS: topeval1(); value_tonumber(&TOP); break; case OP_NOT: { int val = 0; topeval1(); val = value_istrue(&TOP); value_erase(TOP); value_make_bool(TOP, !val); break; } case OP_BNOT: { topeval1(); value_toint32(&TOP); TOP.d.num = (double)(~((int)TOP.d.num)); break; } case OP_ADD: { topeval2(); value_toprimitive(&TOP); value_toprimitive(&TOQ); if (TOP.vt == VT_STRING || TOQ.vt == VT_STRING) { value_tostring(&TOP); value_tostring(&TOQ); unichar *v = unistrcat(TOQ.d.str, TOP.d.str); value_erase(TOQ); value_make_string(TOQ, v); } else { value_tonumber(&TOP); value_tonumber(&TOQ); double n = TOP.d.num + TOQ.d.num; value_erase(TOQ); value_make_number(TOQ, n); } pop(); break; } case OP_SUB: /* god, the notes in ecma is so long, pray to run correctly */ common_math_opr(-); break; case OP_MUL: common_math_opr(*); break; case OP_DIV: common_math_opr(/); break; case OP_MOD: { topeval2(); if (!is_number(&TOP)) value_tonumber(&TOP); if (!is_number(&TOQ)) value_tonumber(&TOQ); TOQ.d.num = fmod(TOQ.d.num, TOP.d.num); pop(); break; } case OP_LESS: topeval2(); logic_less(TOQ, TOP, TOQ); pop(); break; case OP_GREATER: topeval2(); logic_less(TOP, TOQ, TOQ); pop(); break; case OP_LESSEQU: topeval2(); logic_less(TOP, TOQ, TOQ); TOQ.d.val = !TOQ.d.val; pop(); break; case OP_GREATEREQU: topeval2(); logic_less(TOQ, TOP, TOQ); TOQ.d.val = !TOQ.d.val; pop(); break; case OP_EQUAL: case OP_NOTEQUAL: { /* awful, equal opration */ int r = 0; topeval2(); if (TOP.vt != TOQ.vt) { value_toprimitive(&TOP); value_toprimitive(&TOQ); } if (TOP.vt != TOQ.vt) { if ((is_undef(&TOP) || is_null(&TOP)) && (is_undef(&TOQ) || is_null(&TOQ))) { r = 1; } else { value_tonumber(&TOP); value_tonumber(&TOQ); r = (TOP.d.num == TOQ.d.num); } } else { switch (TOP.vt) { case VT_NUMBER: r = (TOP.d.num == TOQ.d.num); break; case VT_BOOL: r = (TOP.d.val == TOQ.d.val); break; case VT_STRING: r = (unistrcmp(TOQ.d.str, TOP.d.str) == 0); break; case VT_OBJECT: /* todo: refer to objects joined to each other */ r = (TOP.d.obj == TOQ.d.obj); break; case VT_UNDEF: case VT_NULL: r = 1; break; default: bug("Unexpected value type\n"); } } r = (ip->op == OP_EQUAL ? r : !r); value_erase(TOQ); value_make_bool(TOQ, r); pop(); break; } case OP_STRICTEQU: case OP_STRICTNEQ: { int r = 0; topeval2(); if (TOP.vt == TOQ.vt) { switch (TOP.vt) { case VT_NUMBER: r = (TOP.d.num == TOQ.d.num); break; case VT_BOOL: r = (TOP.d.val == TOQ.d.val); break; case VT_STRING: r = (unistrcmp(TOQ.d.str, TOP.d.str) == 0); break; case VT_OBJECT: /* todo: refer to objects joined to each other */ r = (TOP.d.obj == TOQ.d.obj); break; case VT_UNDEF: case VT_NULL: r = 1; break; default: bug("Unexpected value type\n"); } } r = (ip->op == OP_STRICTEQU ? r : !r); value_erase(TOQ); value_make_bool(TOQ, r); pop(); break; } case OP_BAND: common_bitwise_opr(&); break; case OP_BOR: common_bitwise_opr(|); break; case OP_BXOR: common_bitwise_opr(^); break; case OP_SHF: { topeval2(); value_toint32(&TOQ); value_toint32(&TOP); int t1 = (int)TOQ.d.num; int t2 = ((unsigned int)TOP.d.num) & 0x1f; if (ip->data) { /* thift right */ if ((int)ip->data == 2) { /* unsigned shift */ unsigned int t3 = (unsigned int)t1; t3 >>= t2; value_make_number(TOQ, t3); } else { t1 >>= t2; value_make_number(TOQ, t1); } } else { t1 <<= t2; value_make_number(TOQ, t1); } pop(); break; }
int parse_config_file(char *path_to_config_file, int need_update) { char line[LINE_SIZE + 2]; char *bufline; char *linepos; char *variable; char *value; size_t count; int lineno; int retval = 0; FILE *cfg_file; strcpy(config_file_path, path_to_config_file); cfg_file = fopen(config_file_path, "r"); if (NULL == cfg_file) { ErrSysLog("can't open '%s' as config file", path_to_config_file); goto EXIT; } ga_variables = malloc(VAR_NAME_SIZE); ga_values = malloc(VAR_VALUE_SIZE); if (need_update) ga_values_backup = malloc(VAR_VALUE_SIZE); if (NULL==ga_variables || NULL==ga_values || (need_update && NULL==ga_values_backup)) { ErrSysLog("malloc failed"); goto EXIT; } /* loop through the whole file */ lineno = 0; while (NULL != fgets(line, sizeof(line), cfg_file)) { lineno++; bufline = line; count = strlen(line); if (count > LINE_SIZE) { ErrSysLog("line too long, conf line skipped %s, line %d", path_to_config_file, lineno); continue; } /* eat the whitespace */ while ((count > 0) && isspace(bufline[0])) { bufline++; count--; } if (count == 0) continue; /* see if this is a comment */ if (bufline[0] == COMMENT_CHARACTER) continue; memcpy(line, bufline, count); line[count] = '\0'; linepos = line; retval = get_key(&linepos, &variable, &value); if (retval != 0) { ErrSysLog("error parsing %s, line %d:%d", path_to_config_file, lineno, (int)(linepos-line)); continue; } if (g_var_num >= MAX_VAR_NUM) { ErrSysLog("too many vars in %s, line %d:%d", path_to_config_file, lineno, (int)(linepos-line)); continue; } if (strlen(variable) > MAX_VAR_NAME_LEN) { ErrSysLog("var name to long %s, line %d:%d", path_to_config_file, lineno, (int)(linepos-line)); continue; } if (strlen(value) > MAX_VAR_VALUE_LEN) { ErrSysLog("value to long %s, line %d:%d", path_to_config_file, lineno, (int)(linepos-line)); continue; } strncpy(ga_variables[g_var_num], variable, sizeof(ga_variables[g_var_num])); remove_trailing_chars(value, '/'); strncpy(ga_values[g_var_num], value, sizeof(ga_values[g_var_num])); g_var_num++; continue; } if (ga_values_backup) value_copy(ga_values_backup, ga_values, g_var_num); EXIT: fclose(cfg_file); return g_var_num; }
int c_value_print (value_ptr val, struct ui_file *stream, int format, enum val_prettyprint pretty) { struct type *type = VALUE_TYPE (val); struct type *real_type; int full, top, using_enc; /* If it is a pointer, indicate what it points to. Print type also if it is a reference. C++: if it is a member pointer, we will take care of that when we print it. */ if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF) { /* Hack: remove (char *) for char strings. Their type is indicated by the quoted string anyway. */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_NAME (type) == NULL && TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL && STREQ (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char")) { /* Print nothing */ } else if (objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) { if (TYPE_CODE(type) == TYPE_CODE_REF) { /* Copy value, change to pointer, so we don't get an * error about a non-pointer type in value_rtti_target_type */ value_ptr temparg; temparg=value_copy(val); VALUE_TYPE (temparg) = lookup_pointer_type(TYPE_TARGET_TYPE(type)); val=temparg; } /* Pointer to class, check real type of object */ fprintf_filtered (stream, "("); real_type = value_rtti_target_type (val, &full, &top, &using_enc); if (real_type) { /* RTTI entry found */ if (TYPE_CODE (type) == TYPE_CODE_PTR) { /* create a pointer type pointing to the real type */ type = lookup_pointer_type (real_type); } else { /* create a reference type referencing the real type */ type = lookup_reference_type (real_type); } /* JYG: Need to adjust pointer value. */ val->aligner.contents[0] -= top; /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); } else { /* normal case */ fprintf_filtered (stream, "("); type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); } } if (objectprint && (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_CLASS)) { /* Attempt to determine real type of object */ real_type = value_rtti_type (val, &full, &top, &using_enc); if (real_type) { /* We have RTTI information, so use it */ val = value_full_object (val, real_type, full, top, using_enc); fprintf_filtered (stream, "(%s%s) ", TYPE_NAME (real_type), full ? "" : " [incomplete object]"); /* Print out object: enclosing type is same as real_type if full */ return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } else if (type != VALUE_ENCLOSING_TYPE (val)) { /* No RTTI information, so let's do our best */ fprintf_filtered (stream, "(%s ?) ", TYPE_NAME (VALUE_ENCLOSING_TYPE (val))); return val_print (VALUE_ENCLOSING_TYPE (val), VALUE_CONTENTS_ALL (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); } /* Otherwise, we end up at the return outside this "if" */ } return val_print (type, VALUE_CONTENTS_ALL (val), VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val), stream, format, 1, 0, pretty); }
/* * A parser for values, inspired somewhat by Scheme/LISP S-expressions * and Prolog/Erlang terms. */ int value_discern(struct value *top, struct scanner *sc) { if (scanner_tokeq(sc, "<")) { struct chain *front, *back; struct value tag, inner; unsigned int size = 1; /* Tuple. */ scanner_scan(sc); value_discern(&tag, sc); scanner_expect(sc, ":"); value_discern(&inner, sc); back = front = add_to_chain(NULL, &inner); while (scanner_tokeq(sc, ",")) { scanner_scan(sc); value_discern(&inner, sc); back = add_to_chain(back, &inner); size++; } scanner_expect(sc, ">"); value_tuple_new(top, &tag, size); populate_tuple_from_chain(top, front); free_chain(front); return 1; } else if (scanner_tokeq(sc, "[")) { struct value inner, *left, right; /* List: Sequence of tail-nested Pairs. */ scanner_scan(sc); if (scanner_tokeq(sc, "]")) { scanner_scan(sc); value_copy(top, &VNULL); return 1; } value_tuple_new(top, &tag_list, 2); value_discern(&inner, sc); value_tuple_store(top, 0, &inner); /*value_tuple_store(top, 1, VNULL);*/ left = top; while (scanner_tokeq(sc, ",")) { scanner_scan(sc); value_tuple_new(&right, &tag_list, 2); value_discern(&inner, sc); value_tuple_store(&right, 0, &inner); /*value_set_index(right, 1, VNULL);*/ value_tuple_store(left, 1, &right); left = value_tuple_fetch(left, 1); } if (scanner_tokeq(sc, "|")) { scanner_scan(sc); value_discern(&right, sc); value_tuple_store(left, 1, &right); } scanner_expect(sc, "]"); return 1; } else if (scanner_tokeq(sc, "{")) { struct value left, right; /* Dictionary: associations between keys and values. */ scanner_scan(sc); value_dict_new(top, 31); value_discern(&left, sc); scanner_expect(sc, "="); value_discern(&right, sc); value_dict_store(top, &left, &right); while (scanner_tokeq(sc, ",")) { scanner_scan(sc); value_discern(&left, sc); scanner_expect(sc, "="); value_discern(&right, sc); value_dict_store(top, &left, &right); } scanner_expect(sc, "}"); return 1; } else if (k_isdigit(scanner_token_string(sc)[0])) { /* Integer. */ value_integer_set(top, k_atoi(scanner_token_string(sc), scanner_token_length(sc))); scanner_scan(sc); return 1; } else { /* Symbol. */ value_symbol_new(top, scanner_token_string(sc), scanner_token_length(sc)); scanner_scan(sc); return 1; } }
int c_value_print (struct value *val, struct ui_file *stream, const struct value_print_options *options) { struct type *type, *real_type, *val_type; int full, top, using_enc; struct value_print_options opts = *options; opts.deref_ref = 1; /* If it is a pointer, indicate what it points to. Print type also if it is a reference. C++: if it is a member pointer, we will take care of that when we print it. */ /* Preserve the original type before stripping typedefs. We prefer to pass down the original type when possible, but for local checks it is better to look past the typedefs. */ val_type = value_type (val); type = check_typedef (val_type); if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF) { /* Hack: remove (char *) for char strings. Their type is indicated by the quoted string anyway. (Don't use c_textual_element_type here; quoted strings are always exactly (char *), (wchar_t *), or the like. */ if (TYPE_CODE (val_type) == TYPE_CODE_PTR && TYPE_NAME (val_type) == NULL && TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)), "char") == 0 || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type))))) { /* Print nothing */ } else if (options->objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) { if (TYPE_CODE(type) == TYPE_CODE_REF) { /* Copy value, change to pointer, so we don't get an * error about a non-pointer type in value_rtti_target_type */ struct value *temparg; temparg=value_copy(val); deprecated_set_value_type (temparg, lookup_pointer_type (TYPE_TARGET_TYPE(type))); val=temparg; } /* Pointer to class, check real type of object */ fprintf_filtered (stream, "("); real_type = value_rtti_target_type (val, &full, &top, &using_enc); if (real_type) { /* RTTI entry found */ if (TYPE_CODE (type) == TYPE_CODE_PTR) { /* create a pointer type pointing to the real type */ type = lookup_pointer_type (real_type); } else { /* create a reference type referencing the real type */ type = lookup_reference_type (real_type); } /* JYG: Need to adjust pointer value. */ /* NOTE: cagney/2005-01-02: THIS IS BOGUS. */ value_contents_writeable (val)[0] -= top; /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } type_print (type, "", stream, -1); fprintf_filtered (stream, ") "); val_type = type; } else { /* normal case */ fprintf_filtered (stream, "("); type_print (value_type (val), "", stream, -1); fprintf_filtered (stream, ") "); } } if (!value_initialized (val)) fprintf_filtered (stream, " [uninitialized] "); if (options->objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS)) { /* Attempt to determine real type of object */ real_type = value_rtti_type (val, &full, &top, &using_enc); if (real_type) { /* We have RTTI information, so use it */ val = value_full_object (val, real_type, full, top, using_enc); fprintf_filtered (stream, "(%s%s) ", TYPE_NAME (real_type), full ? "" : _(" [incomplete object]")); /* Print out object: enclosing type is same as real_type if full */ return val_print (value_enclosing_type (val), value_contents_all (val), 0, value_address (val), stream, 0, &opts, current_language); /* Note: When we look up RTTI entries, we don't get any information on const or volatile attributes */ } else if (type != check_typedef (value_enclosing_type (val))) { /* No RTTI information, so let's do our best */ fprintf_filtered (stream, "(%s ?) ", TYPE_NAME (value_enclosing_type (val))); return val_print (value_enclosing_type (val), value_contents_all (val), 0, value_address (val), stream, 0, &opts, current_language); } /* Otherwise, we end up at the return outside this "if" */ } return val_print (val_type, value_contents_all (val), value_embedded_offset (val), value_address (val), stream, 0, &opts, current_language); }