Esempio n. 1
0
File: forms.c Progetto: bieber/col
/*** 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;

}
Esempio n. 2
0
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;
}
Esempio n. 3
0
File: forms.c Progetto: bieber/col
/*** 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();
    }
}
Esempio n. 4
0
File: forms.c Progetto: bieber/col
/*** 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;
}
Esempio n. 5
0
File: list.c Progetto: dyama/supoo
/* リストの末尾から要素を取り出す */
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
/* 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);
    }
Esempio n. 9
0
/** 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;
}
Esempio n. 10
0
File: list.c Progetto: dyama/supoo
/* リストの先頭から要素を取り出す */
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
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_);
    }
  }
}
Esempio n. 13
0
File: forms.c Progetto: bieber/col
/*** 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;
}
Esempio n. 14
0
/* 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);
}
Esempio n. 15
0
/**
 * 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;
}
Esempio n. 16
0
/*
 * 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);
}
Esempio n. 17
0
/* 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;
}
Esempio n. 18
0
/* 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;
}
Esempio n. 19
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);
}
Esempio n. 20
0
/* 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);
}
Esempio n. 21
0
/**
 * 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;
}
Esempio n. 22
0
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;
}
Esempio n. 24
0
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);
}
Esempio n. 25
0
/*
 * 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;
	}
}
Esempio n. 26
0
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);
}