예제 #1
0
// Exports the given xml key value pair as an xml child of the given parent node
static void xdebug_array_element_export_xml_node(xdebug_xml_node& parent,
                                                 const char* parentName,
                                                 const Variant& key,
                                                 const Variant& val,
                                                 XDebugExporter& exporter) {
  String key_str = key.toString();
  Variant full_name = init_null();

  // Construct the full name
  StringBuffer buf;
  if (parentName != nullptr)  {
    if (key.isInteger()) {
      buf.printf("%s[%s]", parentName, key_str.data());
    } else {
      buf.printf("%s['%s']", parentName, key_str.data());
    }
    full_name = buf.detach();
  }
  const char* full_name_str = full_name.isNull() ?
    nullptr : full_name.toString().data();

  // Recursively add the child
  xdebug_xml_node* child = xdebug_var_export_xml_node(xdstrdup(key_str.data()),
                                                      xdstrdup(full_name_str),
                                                      nullptr,
                                                      val, exporter);
  xdebug_xml_add_child(&parent, child);
}
예제 #2
0
xdebug_xml_node* xdebug_get_value_xml_node(const char* name,
                                           const Variant& val,
                                           XDebugVarType type
                                            /* = XDebugVarType::Normal */,
                                           XDebugExporter& exporter) {
  // Compute the short and full name of the passed value
  char* short_name = nullptr;
  char* full_name = nullptr;
  if (name) {
    switch (type) {
      case XDebugVarType::Normal: {
        char* tmp_name = prepare_variable_name(name);
        short_name = xdstrdup(tmp_name);
        full_name = xdstrdup(tmp_name);
        xdfree(tmp_name);
        break;
      }
      case XDebugVarType::Static:
        short_name = xdebug_sprintf("::%s", name);
        full_name =  xdebug_sprintf("::%s", name);
        break;
      case XDebugVarType::Constant:
        short_name = xdstrdup(name);
        full_name =  xdstrdup(name);
        break;
      default:
        throw Exception("Invalid variable type");
    }
  }

  // Recursively construct the xml
  return xdebug_var_export_xml_node(short_name, full_name, nullptr,
                                    val, exporter);
}
예제 #3
0
static void xdebug_object_element_export_xml_node(xdebug_xml_node& parent,
                                                  const char* parentName,
                                                  const ObjectData* obj,
                                                  const Variant& key,
                                                  const Variant& val,
                                                  XDebugExporter& exporter) {
  auto const prop_str = key.toString();
  auto const cls = obj->getVMClass();
  auto const cls_name = cls->name()->data();

  // Compute whether the properity is static.

  auto const sLookup = cls->getSProp(nullptr, prop_str.get());

  auto const is_static = sLookup.prop != nullptr;
  bool visible = is_static;
  bool accessible = sLookup.accessible;

  // If the property is not static, we know it's a member, but need to grab the
  // visibility
  if (!is_static) {
    bool unset;
    obj->getProp(nullptr, prop_str.get(), visible, accessible, unset);
  }

  // This is public if it is visible and accessible from the nullptr context
  bool is_public = visible && accessible;

  // Compute the property name and full name
  const char* name;
  const char* full_name = nullptr;
  if (!val.isInteger()) {
    // Compute the property name
    if (is_public) {
      name = xdstrdup(prop_str.data());
    } else {
      name = xdebug_sprintf("*%s*%s", cls_name, prop_str.data());
    }

    // Compute the property full name if we have a parent name
    if (parentName != nullptr) {
      if (is_public && is_static) {
        full_name = xdebug_sprintf("%s::%s", parentName, prop_str.data());
      } else if (is_public && !is_static) {
        full_name = xdebug_sprintf("%s->%s", parentName, prop_str.data());
      } else if (!is_public && is_static) {
        full_name = xdebug_sprintf("%s::*%s*%s", parentName, "::",
                                   cls_name, prop_str.data());
      } else if (!is_public && !is_static) {
        full_name = xdebug_sprintf("%s->*%s*%s", parentName, "->",
                                   cls_name, prop_str.data());
      }
    }
  } else {
    // Compute the name + full name if we have a parent name
    name = xdebug_sprintf("%ld", key.toInt64());
    if (parentName != nullptr) {
      if (is_static) {
        full_name = xdebug_sprintf("%s::%ld", parentName, key.toInt64());
      } else {
        full_name = xdebug_sprintf("%s->%ld", parentName, key.toInt64());
      }
    }
  }

  // Compute the facet (static/non-static + public/private)
  const char* facet = xdebug_sprintf("%s%s",
                                     is_static ? "static " : "",
                                     is_public ? "public" : "private");

  // Recursively write the this property. The duplications are necessary due to
  // the xdebug xml api
  xdebug_xml_node* child = xdebug_var_export_xml_node(xdstrdup(name),
                                                      xdstrdup(full_name),
                                                      xdstrdup(facet),
                                                      val, exporter);
  xdebug_xml_add_child(&parent, child);
}