Esempio n. 1
0
Variant c_DebuggerClient::t_init(CVarRef options) {
  INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClient, DebuggerClient::init);
  if (!m_client) {
    raise_warning("invalid client");
    return false;
  }
  if (m_client->getClientState() != DebuggerClient::StateUninit) {
    return m_client->getClientState() == DebuggerClient::StateReadyForCommand;
  }
  if (!options.isArray()) {
    raise_warning("options must be an array");
    return false;
  }
  m_client->setClientState(DebuggerClient::StateInitializing);

  DebuggerClientOptions ops;
  ops.apiMode = true;

  Array opsArr = options.toArray();
  if (opsArr.exists("user")) {
    ops.user = opsArr.rvalAtRef("user").toString().data();
  } else {
    raise_warning("must specify user in options");
    return false;
  }

  if (opsArr.exists("configFName")) {
    ops.configFName = opsArr.rvalAtRef("configFName").toString().data();
    FILE *f = fopen(ops.configFName.c_str(), "r");
    if (!f) {
      raise_warning("cannot access config file %s", ops.configFName.c_str());
      return false;
    }
    fclose(f);
  }

  if (opsArr.exists("host")) {
    ops.host = opsArr.rvalAtRef("host").toString().data();
  }
  if (opsArr.exists("port")) {
    ops.port = opsArr.rvalAtRef("port").toInt32();
  }
  if (opsArr.exists("sandbox")) {
    ops.sandbox = opsArr.rvalAtRef("sandbox").toString().data();
  }

  m_client->init(ops);

  if (ops.host.empty()) {
    ops.host = "localhost";
  }
  if (ops.port < 0) {
    ops.port = RuntimeOption::DebuggerServerPort;
  }
  bool ret = m_client->connect(ops.host, ops.port);
  if (!ret) {
    raise_warning("failed to connect to hhvm %s:%d", ops.host.c_str(),
                  ops.port);
    return false;
  }

  // To wait for the session start interrupt
  DebuggerCommandPtr cmd = m_client->waitForNextInterrupt();
  if (!cmd->is(DebuggerCommand::KindOfInterrupt) ||
      dynamic_pointer_cast<CmdInterrupt>(cmd)->getInterruptType() !=
      SessionStarted) {
    raise_warning("failed to load sandbox");
    return false;
  }

  ret = m_client->initializeMachine();
  if (!ret) {
    raise_warning("failed to initialize machine info");
    return false;
  }

  // To wait for the machine loading sandbox
  cmd = m_client->waitForNextInterrupt();
  if (!cmd->is(DebuggerCommand::KindOfInterrupt) ||
      dynamic_pointer_cast<CmdInterrupt>(cmd)->getInterruptType() !=
      SessionStarted) {
    raise_warning("failed to load sandbox");
    return false;
  }

  m_client->setClientState(DebuggerClient::StateReadyForCommand);

  return true;
}
Variant VariableStringPropertyExpression::evalExist(VariableEnvironment &env)
  const {
  CVarRef lv = m_obj->getRef(env);
  SET_LINE;
  return lv.o_get(m_name, false);
}
Esempio n. 3
0
String String::rvalAt(CVarRef key) const {
    return rvalAtImpl(key.toInt32());
}
Esempio n. 4
0
bool f_is_numeric(CVarRef v) {
  return v.isNumeric(true);
}
Esempio n. 5
0
bool f_is_object(CVarRef var) {
  return var.is(KindOfObject) && !var.isResource();
}
Esempio n. 6
0
int64_t f_intval(CVarRef v, int64_t base /* = 10 */) { return v.toInt64(base);}
Esempio n. 7
0
double f_floatval(CVarRef v) { return v.toDouble();}
Esempio n. 8
0
Variant ArrayUtil::Splice(CArrRef input, int offset, int64_t length /* = 0 */,
                          CVarRef replacement /* = null_variant */,
                          Array *removed /* = NULL */) {
  int num_in = input.size();
  if (offset > num_in) {
    offset = num_in;
  } else if (offset < 0 && (offset = (num_in + offset)) < 0) {
    offset = 0;
  }

  if (length < 0) {
    length = num_in - offset + length;
  } else if (((unsigned)offset + (unsigned)length) > (unsigned)num_in) {
    length = num_in - offset;
  }

  Array out_hash = Array::Create();
  int pos = 0;
  ArrayIter iter(input);
  for (; pos < offset && iter; ++pos, ++iter) {
    Variant key(iter.first());
    CVarRef v = iter.secondRef();
    if (key.isNumeric()) {
      out_hash.appendWithRef(v);
    } else {
      out_hash.setWithRef(key, v, true);
    }
  }

  for (; pos < offset + length && iter; ++pos, ++iter) {
    if (removed) {
      Variant key(iter.first());
      CVarRef v = iter.secondRef();
      if (key.isNumeric()) {
        removed->appendWithRef(v);
      } else {
        removed->setWithRef(key, v, true);
      }
    }
  }

  Array arr = replacement.toArray();
  if (!arr.empty()) {
    for (ArrayIter iter(arr); iter; ++iter) {
      CVarRef v = iter.secondRef();
      out_hash.appendWithRef(v);
    }
  }

  for (; iter; ++iter) {
    Variant key(iter.first());
    CVarRef v = iter.secondRef();
    if (key.isNumeric()) {
      out_hash.appendWithRef(v);
    } else {
      out_hash.setWithRef(key, v, true);
    }
  }

  return out_hash;
}
Esempio n. 9
0
static String get_classname(CVarRef class_or_object) {
  if (class_or_object.is(KindOfObject)) {
    return class_or_object.toCObjRef().get()->o_getClassName();
  }
  return class_or_object.toString();
}
Esempio n. 10
0
bool f_is_callable(CVarRef v, bool syntax /* = false */,
                   VRefParam name /* = null */) {
  bool ret = true;
  if (LIKELY(!syntax)) {
    CallerFrame cf;
    ObjectData* obj = NULL;
    HPHP::Class* cls = NULL;
    StringData* invName = NULL;
    const HPHP::Func* f = vm_decode_function(v, cf(), false, obj, cls,
                                                 invName, false);
    if (f == NULL) {
      ret = false;
    }
    if (invName != NULL) {
      decRefStr(invName);
    }
    if (!name.isReferenced()) return ret;
  }

  auto const tv_func = v.asCell();
  if (IS_STRING_TYPE(tv_func->m_type)) {
    if (name.isReferenced()) name = tv_func->m_data.pstr;
    return ret;
  }

  if (tv_func->m_type == KindOfArray) {
    CArrRef arr = tv_func->m_data.parr;
    CVarRef clsname = arr.rvalAtRef(int64_t(0));
    CVarRef mthname = arr.rvalAtRef(int64_t(1));
    if (arr.size() != 2 ||
        &clsname == &null_variant ||
        &mthname == &null_variant) {
      name = v.toString();
      return false;
    }

    auto const tv_meth = mthname.asCell();
    if (!IS_STRING_TYPE(tv_meth->m_type)) {
      if (name.isReferenced()) name = v.toString();
      return false;
    }

    auto const tv_cls = clsname.asCell();
    if (tv_cls->m_type == KindOfObject) {
      name = tv_cls->m_data.pobj->o_getClassName();
    } else if (IS_STRING_TYPE(tv_cls->m_type)) {
      name = tv_cls->m_data.pstr;
    } else {
      name = v.toString();
      return false;
    }

    name = concat3(name, s_colon2, tv_meth->m_data.pstr);
    return ret;
  }

  if (tv_func->m_type == KindOfObject) {
    ObjectData *d = tv_func->m_data.pobj;
    const Func* invoke = d->getVMClass()->lookupMethod(s__invoke.get());
    if (name.isReferenced()) {
      if (d->instanceof(c_Closure::s_cls)) {
        // Hack to stop the mangled name from showing up
        name = s_Closure__invoke;
      } else {
        name = d->o_getClassName() + "::__invoke";
      }
    }
    return invoke != NULL;
  }

  return false;
}
Esempio n. 11
0
void BaseVector::construct(CVarRef iterable /* = null_variant */) {
  if (iterable.isNull()) return;
  init(iterable);
}
Esempio n. 12
0
Variant f_substr_replace(CVarRef str, CVarRef replacement, CVarRef start,
                         CVarRef length /* = 0x7FFFFFFF */) {
  if (!str.is(KindOfArray)) {
    String repl;
    if (replacement.is(KindOfArray)) {
      repl = replacement[0].toString();
    } else {
      repl = replacement.toString();
    }
    if (start.is(KindOfArray)) {
      if (!length.is(KindOfArray)) {
        throw_invalid_argument("start and length should be of same type - "
                               "numerical or array");
        return str;
      }
      Array startArr = start.toArray();
      Array lengthArr = length.toArray();
      if (startArr.size() != lengthArr.size()) {
        throw_invalid_argument("start and length: (different item count)");
        return str;
      }
      throw_invalid_argument("start and length as arrays not implemented");
      return str;
    }
    return str.toString().replace(start.toInt32(), length.toInt32(), repl);
  }

  Array ret;
  Array strArr = str.toArray();
  Array startArr = start.toArray();
  Array lengthArr = length.toArray();
  ArrayIter startIter(startArr);
  ArrayIter lengthIter(lengthArr);

  if (replacement.is(KindOfArray)) {
    Array replArr = replacement.toArray();
    ArrayIter replIter(replArr);
    for (ArrayIter iter(strArr); iter;
         ++iter, ++startIter, ++lengthIter) {
      int nStart = startIter.second().toInt32();
      int nLength = lengthIter.second().toInt32();
      String repl("");
      if (replIter) {
        repl = replIter.second().toString();
        ++replIter;
      }
      ret.append(iter.second().toString().replace(nStart, nLength, repl));
    }
  } else {
    String repl = replacement.toString();
    for (ArrayIter iter(strArr); iter;
         ++iter, ++startIter, ++lengthIter) {
      int nStart = startIter.second().toInt32();
      int nLength = lengthIter.second().toInt32();
      ret.append(iter.second().toString().replace(nStart, nLength, repl));
    }
  }
  return ret;
}
Esempio n. 13
0
bool f_is_callable(CVarRef v, bool syntax /* = false */,
                   VRefParam name /* = null */) {
  bool ret = true;
  if (LIKELY(!syntax)) {
    if (hhvm) {
      CallerFrame cf;
      ObjectData* obj = NULL;
      HPHP::VM::Class* cls = NULL;
      StringData* invName = NULL;
      const HPHP::VM::Func* f = vm_decode_function(v, cf(), false, obj, cls,
                                                   invName, false);
      if (f == NULL) {
        ret = false;
      }
      if (invName != NULL) {
        LITSTR_DECREF(invName);
      }
    } else {
      MethodCallPackage mcp;
      String classname, methodname;
      bool doBind;
      ret = get_user_func_handler(v, true, mcp,
                                  classname, methodname, doBind, false);
      if (ret && mcp.ci->m_flags & (CallInfo::Protected|CallInfo::Private)) {
        classname = mcp.getClassName();
        if (!ClassInfo::HasAccess(classname, *mcp.name,
                                  mcp.ci->m_flags & CallInfo::StaticMethod ||
                                  !mcp.obj,
                                  mcp.obj)) {
          ret = false;
        }
      }
    }
    if (!name.isReferenced()) return ret;
  }

  Variant::TypedValueAccessor tv_func = v.getTypedAccessor();
  if (Variant::IsString(tv_func)) {
    if (name.isReferenced()) name = Variant::GetStringData(tv_func);
    return ret;
  }

  if (Variant::GetAccessorType(tv_func) == KindOfArray) {
    CArrRef arr = Variant::GetAsArray(tv_func);
    CVarRef clsname = arr.rvalAtRef(0LL);
    CVarRef mthname = arr.rvalAtRef(1LL);
    if (arr.size() != 2 ||
        &clsname == &null_variant ||
        &mthname == &null_variant) {
      name = v.toString();
      return false;
    }

    Variant::TypedValueAccessor tv_meth = mthname.getTypedAccessor();
    if (!Variant::IsString(tv_meth)) {
      if (name.isReferenced()) name = v.toString();
      return false;
    }

    Variant::TypedValueAccessor tv_cls = clsname.getTypedAccessor();
    if (Variant::GetAccessorType(tv_cls) == KindOfObject) {
      name = Variant::GetObjectData(tv_cls)->o_getClassName();
    } else if (Variant::IsString(tv_cls)) {
      name = Variant::GetStringData(tv_cls);
    } else {
      name = v.toString();
      return false;
    }

    name = concat3(name, "::", Variant::GetAsString(tv_meth));
    return ret;
  }

  if (Variant::GetAccessorType(tv_func) == KindOfObject) {
    ObjectData *d = Variant::GetObjectData(tv_func);
    if (hhvm) {
      static const StringData* sd__invoke
        = StringData::GetStaticString("__invoke");
      const VM::Func* invoke = d->getVMClass()->lookupMethod(sd__invoke);
      if (name.isReferenced()) {
        if (d->o_instanceof("closure")) {
          // Hack to stop the mangled name from showing up
          name = "Closure::__invoke";
        } else {
          name = d->o_getClassName() + "::__invoke";
        }
      }
      return invoke != NULL;
    } else {
      void *extra;
      if (d->t___invokeCallInfoHelper(extra)) {
        name = d->o_getClassName() + "::__invoke";
        return ret;
      }
      if (name.isReferenced()) {
        name = v.toString();
      }
    }
  }

  return false;
}
Esempio n. 14
0
Variant c_DebuggerClient::t_processcmd(CVarRef cmdName, CVarRef args) {
  INSTANCE_METHOD_INJECTION_BUILTIN(DebuggerClient, DebuggerClient::processcmd);
  if (!m_client ||
      m_client->getClientState() < DebuggerClient::StateReadyForCommand) {
    raise_warning("client is not initialized");
    return null;
  }
  if (m_client->getClientState() != DebuggerClient::StateReadyForCommand) {
    raise_warning("client is not ready to take command");
    return null;
  }
  if (!cmdName.isString()) {
    raise_warning("cmdName must be string");
    return null;
  }
  if (!args.isNull() && !args.isArray()) {
    raise_warning("args must be null or array");
    return null;
  }

  static const char *s_allowedCmds[] = {
    "break", "continue", "down", "exception", "frame", "global",
    "help", "info", "konstant", "next", "out", "print", "quit", "step",
    "up", "variable", "where", "bt", "set", "inst", "=", "@", NULL
  };

  bool allowed = false;
  for (int i = 0; ; i++) {
    const char *cmd = s_allowedCmds[i];
    if (cmd == NULL) {
      break;
    }
    if (cmdName.same(cmd)) {
      allowed = true;
      break;
    }
  }
  if (!allowed) {
    raise_warning("unsupported command %s", cmdName.toString().data());
    return null;
  }

  m_client->setCommand(cmdName.toString().data());
  StringVec *clientArgs = m_client->args();
  clientArgs->clear();
  if (!args.isNull()) {
    for (ArrayIter iter(args.toArray()); iter; ++iter) {
      CStrRef arg = iter.second().toString();
      clientArgs->push_back(std::string(arg.data(), arg.size()));
    }
  }
  try {
    if (!m_client->process()) {
      raise_warning("command \"%s\" not found", cmdName.toString().data());
    }
  } catch (DebuggerConsoleExitException &e) {
    // Flow-control command goes here
    Logger::Info("wait for debugger client to stop");
    m_client->setTakingInterrupt();
    m_client->setClientState(DebuggerClient::StateBusy);
    DebuggerCommandPtr cmd = m_client->waitForNextInterrupt();
    if (!cmd) {
      raise_warning("not getting a command");
    } else if (cmd->is(DebuggerCommand::KindOfInterrupt)) {
      CmdInterruptPtr cmdInterrupt = dynamic_pointer_cast<CmdInterrupt>(cmd);
      cmdInterrupt->onClientD(m_client);
    } else {
      // Previous pending commands
      cmd->handleReply(m_client);
      cmd->setClientOutput(m_client);
    }
    Logger::Info("debugger client ready for command");
  } catch (DebuggerClientExitException &e) {
    const std::string& nameStr = m_client->getNameApi();
    Logger::Info("client %s disconnected", nameStr.c_str());
    s_dbgCltMap.erase(nameStr);
    delete m_client;
    m_client = NULL;
    return true;
  } catch (DebuggerProtocolException &e) {
    raise_warning("DebuggerProtocolException");
    return null;
  }

  return m_client->getOutputArray();
}
Esempio n. 15
0
bool f_is_scalar(CVarRef v) {
  return v.isScalar();
}
Esempio n. 16
0
void Globals::initialize() {
  StaticInits *s = s_next_inits;
  while (s) {
    const ClassPropTable *cpt = s->table;
    const int *e = s->entries;
    int n = *e++;
    while (n--) {
      const ClassPropTableEntry *p = cpt->m_entries + *e++;
      char *addr = (char*)this + p->offset;
      if (LIKELY(p->isFastInit())) {
        CVarRef v = cpt->getInitV(p->init_offset);
        switch (p->type) {
          case KindOfBoolean:
            *(bool*)addr = v.asBooleanVal();
            break;
          case KindOfInt64:
            *(int64*)addr = v.asInt64Val();
            break;
          case KindOfDouble:
            *(double*)addr = v.asDoubleVal();
            break;
          case KindOfString:
            *(String*)addr = v.asCStrRef();
            break;
          case KindOfArray:
            *(Array*)addr = v.asCArrRef();
            break;
          case KindOfVariant:
            *(Variant*)addr = v;
            break;
          default:
            ASSERT(false);
        }
        continue;
      }
      CVarRef v = cpt->getInitVal(p);
      if (LIKELY(p->type == KindOfVariant)) {
        *(Variant*)addr = v;
      } else {
        switch (p->type) {
          case KindOfBoolean:
            *(bool*)addr = v;
            break;
          case KindOfInt64:
            *(int64*)addr = v;
            break;
          case KindOfDouble:
            *(double*)addr = v;
            break;
          case KindOfString:
            *(String*)addr = v;
            break;
          case KindOfArray:
            *(Array*)addr = v;
            break;
          default:
            ASSERT(false);
        }
      }
    }
    s = s->next;
  }
}
Esempio n. 17
0
bool f_is_resource(CVarRef v) {
  return v.isResource();
}
Esempio n. 18
0
Variant f_hphp_process_abort(CVarRef magic) {
  if (magic.equal("I solemnly swear that I am up to no good.")) {
    *((int*)0) = 0xdead;
  }
  return null_variant;
}
Esempio n. 19
0
double f_doubleval(CVarRef v) { return v.toDouble();}
Esempio n. 20
0
Variant f_get_class(CVarRef object /* = null_variant */) {
  if (!object.isObject()) return false;
  return object.toObject()->o_getClassName();
}
Esempio n. 21
0
String f_strval(CVarRef v) { return v.toString();}
Esempio n. 22
0
Variant f_get_object_vars(CVarRef object) {
  if (object.isObject()) {
    return object.toObject()->o_toIterArray(FrameInjection::GetClassName(true));
  }
  return false;
}
Esempio n. 23
0
Variant c_Memcache::t_get(CVarRef key, Variant flags /*= null*/) {
  INSTANCE_METHOD_INJECTION_BUILTIN(Memcache, Memcache::get);
  if (key.is(KindOfArray)) {
    std::vector<const char *> real_keys;
    std::vector<size_t> key_len;
    Array keyArr = key.toArray();

    real_keys.reserve(keyArr.size());
    key_len.reserve(keyArr.size());

    for (ArrayIter iter(keyArr); iter; ++iter) {
      real_keys.push_back(const_cast<char *>(iter.second().toString().c_str()));
      key_len.push_back(iter.second().toString().length());
    }

    if (!real_keys.empty()) {
      const char *payload = NULL;
      size_t payload_len = 0;
      uint32_t flags = 0;
      const char *res_key = NULL;
      size_t res_key_len = 0;

      memcached_result_st result;

      memcached_return_t ret = memcached_mget(&m_memcache, &real_keys[0],
                                              &key_len[0], real_keys.size());
      memcached_result_create(&m_memcache, &result);
      Array return_val;

      while ((memcached_fetch_result(&m_memcache, &result, &ret)) != NULL) {
        if (ret != MEMCACHED_SUCCESS) {
          // should probably notify about errors
          continue;
        }

        payload     = memcached_result_value(&result);
        payload_len = memcached_result_length(&result);
        flags       = memcached_result_flags(&result);
        res_key     = memcached_result_key_value(&result);
        res_key_len = memcached_result_key_length(&result);

        return_val.set(String(res_key, res_key_len, CopyString),
                       memcache_fetch_from_storage(payload,
                                                   payload_len, flags));
      }
      memcached_result_free(&result);

      return return_val;
    }
  } else if (key.isString()) {
    char *payload = NULL;
    size_t payload_len = 0;
    uint32_t flags = 0;

    memcached_return_t ret;
    String skey = key.toString();
    payload = memcached_get(&m_memcache, skey.c_str(), skey.length(),
                            &payload_len, &flags, &ret);

    /* This is for historical reasons from libmemcached*/
    if (ret == MEMCACHED_END) {
      ret = MEMCACHED_NOTFOUND;
    }

    if (ret == MEMCACHED_NOTFOUND) {
      return false;
    }

    Variant retval = memcache_fetch_from_storage(payload, payload_len, flags);
    free(payload);

    return retval;
  }

  return false;
}
Esempio n. 24
0
Variant f_range(CVarRef low, CVarRef high, CVarRef step /* = 1 */) {
  bool is_step_double = false;
  double dstep = 1.0;
  if (step.isDouble()) {
    dstep = step.toDouble();
    is_step_double = true;
  } else if (step.isString()) {
    int64_t sn;
    double sd;
    DataType stype = step.toString()->isNumericWithVal(sn, sd, 0);
    if (stype == KindOfDouble) {
      is_step_double = true;
      dstep = sd;
    } else if (stype == KindOfInt64) {
      dstep = (double)sn;
    } else {
      dstep = step.toDouble();
    }
  } else {
    dstep = step.toDouble();
  }
  /* We only want positive step values. */
  if (dstep < 0.0) dstep *= -1;
  if (low.isString() && high.isString()) {
    String slow = low.toString();
    String shigh = high.toString();
    if (slow.size() >= 1 && shigh.size() >=1) {
      int64_t n1, n2;
      double d1, d2;
      DataType type1 = slow->isNumericWithVal(n1, d1, 0);
      DataType type2 = shigh->isNumericWithVal(n2, d2, 0);
      if (type1 == KindOfDouble || type2 == KindOfDouble || is_step_double) {
        if (type1 != KindOfDouble) d1 = slow.toDouble();
        if (type2 != KindOfDouble) d2 = shigh.toDouble();
        return ArrayUtil::Range(d1, d2, dstep);
      }

      int64_t lstep = (int64_t) dstep;
      if (type1 == KindOfInt64 || type2 == KindOfInt64) {
        if (type1 != KindOfInt64) n1 = slow.toInt64();
        if (type2 != KindOfInt64) n2 = shigh.toInt64();
        return ArrayUtil::Range((double)n1, (double)n2, lstep);
      }

      return ArrayUtil::Range((unsigned char)slow.charAt(0),
                              (unsigned char)shigh.charAt(0), lstep);
    }
  }

  if (low.is(KindOfDouble) || high.is(KindOfDouble) || is_step_double) {
    return ArrayUtil::Range(low.toDouble(), high.toDouble(), dstep);
  }

  int64_t lstep = (int64_t) dstep;
  return ArrayUtil::Range(low.toDouble(), high.toDouble(), lstep);
}
Esempio n. 25
0
StringOffset String::lvalAt(CVarRef key) {
  return lvalAtImpl(key.toInt32());
}
Esempio n. 26
0
String f_hphp_to_string(CVarRef v) {
  return v.toString();
}
Esempio n. 27
0
std::string CmdPrint::FormatResult(const char *format, CVarRef ret) {
  if (format == nullptr) {
    String sret = DebuggerClient::FormatVariable(ret, -1);
    return string(sret.data(), sret.size());
  }

  if (strcmp(format, "v") == 0) {
    String sret = DebuggerClient::FormatVariable(ret, -1, true);
    return string(sret.data(), sret.size());
  }

  if (strcmp(format, "dec") == 0 ||
      strcmp(format, "unsigned") == 0 ||
      ret.isInteger()) {
    int64 nret = ret.toInt64();
    char buf[64];
    if (strcmp(format, "hex") == 0 || strcmp(format, "x") == 0) {
      snprintf(buf, sizeof(buf), "%" PRIx64, nret);
      return buf;
    }
    if (strcmp(format, "oct") == 0) {
      snprintf(buf, sizeof(buf), "%" PRIo64, nret);
      return buf;
    }
    if (strcmp(format, "dec") == 0) {
      snprintf(buf, sizeof(buf), "%" PRId64, nret);
      return buf;
    }
    if (strcmp(format, "unsigned") == 0) {
      snprintf(buf, sizeof(buf), "%" PRIu64, nret);
      return buf;
    }
    if (strcmp(format, "time") == 0) {
      StringBuffer sb;
      DateTime dt(nret);
      sb.append("RFC822:            ");
      sb.append(dt.toString(DateTime::RFC822));
      sb.append("\nRFC850:            ");
      sb.append(dt.toString(DateTime::RFC850));
      sb.append("\nRFC1036:           ");
      sb.append(dt.toString(DateTime::RFC1036));
      sb.append("\nRFC1123/RSS:       ");
      sb.append(dt.toString(DateTime::RFC1123));
      sb.append("\nRFC2822:           ");
      sb.append(dt.toString(DateTime::RFC2822));
      sb.append("\nRFC3339/ATOM/W3C:  ");
      sb.append(dt.toString(DateTime::RFC3339));
      sb.append("\nISO8601:           ");
      sb.append(dt.toString(DateTime::ISO8601));
      sb.append("\nCookie:            ");
      sb.append(dt.toString(DateTime::Cookie));
      sb.append("\nHttpHeader:        ");
      sb.append(dt.toString(DateTime::HttpHeader));
      return sb.data();
    }

    assert(false);
  }

  String sret = DebuggerClient::FormatVariable(ret, -1);
  if (strcmp(format, "hex") == 0 || strcmp(format, "x") == 0 ||
      strcmp(format, "oct") == 0) {
    StringBuffer sb;
    for (int i = 0; i < sret.size(); i++) {
      char ch = sret[i];
      if (isprint(ch)) {
        sb.append(ch);
      } else {
        char buf[6];
        if (strcmp(format, "oct") == 0) {
          snprintf(buf, sizeof(buf), "\\%03o", ch);
        } else {
          snprintf(buf, sizeof(buf), "\\x%02x", ch);
        }
        sb.append(buf);
      }
    }
    return sb.data() ? sb.data() : "";
  }
  if (strcmp(format, "time") == 0) {
    DateTime dt;
    int64 ts = -1;
    if (dt.fromString(ret.toString(), SmartObject<TimeZone>())) {
      bool err;
      ts = dt.toTimeStamp(err);
    }
    return String(ts).data();
  }

  assert(false);
  return "";
}
Esempio n. 28
0
Array f_getopt(CStrRef options, CVarRef longopts /* = null_variant */) {
  opt_struct *opts, *orig_opts;
  int len = parse_opts(options.data(), options.size(), &opts);

  if (!longopts.isNull()) {
    Array arropts = longopts.toArray();
    int count = arropts.size();

    /* the first <len> slots are filled by the one short ops
     * we now extend our array and jump to the new added structs */
    opts = (opt_struct *)realloc(opts, sizeof(opt_struct) * (len + count + 1));
    orig_opts = opts;
    opts += len;

    memset(opts, 0, count * sizeof(opt_struct));

    for (ArrayIter iter(arropts); iter; ++iter) {
      String entry = iter.second().toString();

      opts->need_param = 0;
      opts->opt_name = strdup(entry.data());
      len = strlen(opts->opt_name);
      if ((len > 0) && (opts->opt_name[len - 1] == ':')) {
        opts->need_param++;
        opts->opt_name[len - 1] = '\0';
        if ((len > 1) && (opts->opt_name[len - 2] == ':')) {
          opts->need_param++;
          opts->opt_name[len - 2] = '\0';
        }
      }
      opts->opt_char = 0;
      opts++;
    }
  } else {
    opts = (opt_struct*) realloc(opts, sizeof(opt_struct) * (len + 1));
    orig_opts = opts;
    opts += len;
  }

  /* php_getopt want to identify the last param */
  opts->opt_char   = '-';
  opts->need_param = 0;
  opts->opt_name   = NULL;

  static const StaticString s_argv("argv");
  GlobalVariables *g = get_global_variables();
  Array vargv = g->get(s_argv).toArray();
  int argc = vargv.size();
  char **argv = (char **)malloc((argc+1) * sizeof(char*));
  vector<String> holders;
  int index = 0;
  for (ArrayIter iter(vargv); iter; ++iter) {
    String arg = iter.second().toString();
    holders.push_back(arg);
    argv[index++] = (char*)arg.data();
  }
  argv[index] = NULL;

  Array ret = Array::Create();

  /* after our pointer arithmetic jump back to the first element */
  opts = orig_opts;

  int o;
  char *php_optarg = NULL;
  int php_optind = 1;

  Variant val;
  int optchr = 0;
  int dash = 0; /* have already seen the - */
  char opt[2] = { '\0' };
  char *optname;
  int optname_len = 0;
  int php_optidx;
  while ((o = php_getopt(argc, argv, opts, &php_optarg, &php_optind, 0, 1,
                         optchr, dash, php_optidx))
         != -1) {
    /* Skip unknown arguments. */
    if (o == '?') {
      continue;
    }

    /* Prepare the option character and the argument string. */
    if (o == 0) {
      optname = opts[php_optidx].opt_name;
    } else {
      if (o == 1) {
        o = '-';
      }
      opt[0] = o;
      optname = opt;
    }

    if (php_optarg != NULL) {
      /* keep the arg as binary, since the encoding is not known */
      val = String(php_optarg, CopyString);
    } else {
      val = false;
    }

    /* Add this option / argument pair to the result hash. */
    optname_len = strlen(optname);
    if (!(optname_len > 1 && optname[0] == '0') &&
        is_numeric_string(optname, optname_len, NULL, NULL, 0) ==
        KindOfInt64) {
      /* numeric string */
      int optname_int = atoi(optname);
      if (ret.exists(optname_int)) {
        Variant &e = ret.lvalAt(optname_int);
        if (!e.isArray()) {
          ret.set(optname_int, CREATE_VECTOR2(e, val));
        } else {
          e.append(val);
        }
      } else {
        ret.set(optname_int, val);
      }
    } else {
      /* other strings */
      String key(optname, strlen(optname), CopyString);
      if (ret.exists(key)) {
        Variant &e = ret.lvalAt(key);
        if (!e.isArray()) {
          ret.set(key, CREATE_VECTOR2(e, val));
        } else {
          e.append(val);
        }
      } else {
        ret.set(key, val);
      }
    }

    php_optarg = NULL;
  }

  free_longopts(orig_opts);
  free(orig_opts);
  free(argv);
  return ret;
}
int Array::SortRegularAscending(CVarRef v1, CVarRef v2, const void *data) {
    if (v1.less(v2)) return -1;
    if (v1.equal(v2)) return 0;
    return 1;
}
Esempio n. 30
0
bool BuiltinSymbols::Load(AnalysisResultPtr ar) {
  if (Loaded) return true;
  Loaded = true;

  if (g_context.isNull()) init_thread_locals();
  ClassInfo::Load();

  // load extension functions first, so system/php may call them
  ImportExtFunctions(ar, ClassInfo::GetSystem());

  ConstantTablePtr cns = ar->getConstants();
  // load extension constants, classes and dynamics
  ImportNativeConstants(ar, cns);
  ImportExtConstants(ar, cns, ClassInfo::GetSystem());
  ImportExtClasses(ar);

  Array constants = ClassInfo::GetSystemConstants();
  LocationPtr loc(new Location);
  for (ArrayIter it = constants.begin(); it; ++it) {
    CVarRef key = it.first();
    if (!key.isString()) continue;
    std::string name = key.toCStrRef().data();
    if (cns->getSymbol(name)) continue;
    if (name == "true" || name == "false" || name == "null") continue;
    CVarRef value = it.secondRef();
    if (!value.isInitialized() || value.isObject()) continue;
    ExpressionPtr e = Expression::MakeScalarExpression(ar, ar, loc, value);
    TypePtr t =
      value.isNull()    ? Type::Null    :
      value.isBoolean() ? Type::Boolean :
      value.isInteger() ? Type::Int64   :
      value.isDouble()  ? Type::Double  :
      value.isArray()   ? Type::Array   : Type::Variant;

    cns->add(key.toCStrRef().data(), t, e, ar, e);
  }
  for (int i = 0, n = NumGlobalNames(); i < n; ++i) {
    ar->getVariables()->add(GlobalNames[i], Type::Variant, false, ar,
                            ConstructPtr(), ModifierExpressionPtr());
  }

  cns->setDynamic(ar, "PHP_BINARY", true);
  cns->setDynamic(ar, "PHP_BINDIR", true);
  cns->setDynamic(ar, "PHP_OS", true);
  cns->setDynamic(ar, "PHP_SAPI", true);
  cns->setDynamic(ar, "SID", true);

  // Systemlib files were all parsed by hphp_process_init

  const StringToFileScopePtrMap &files = ar->getAllFiles();
  for (const auto& file : files) {
    file.second->setSystem();

    const auto& classes = file.second->getClasses();
    for (const auto& clsVec : classes) {
      assert(clsVec.second.size() == 1);
      auto cls = clsVec.second[0];
      cls->setSystem();
      ar->addSystemClass(cls);
      for (const auto& func : cls->getFunctions()) {
        FunctionScope::RecordFunctionInfo(func.first, func.second);
      }
    }

    const auto& functions = file.second->getFunctions();
    for (const auto& func : functions) {
      func.second->setSystem();
      ar->addSystemFunction(func.second);
      FunctionScope::RecordFunctionInfo(func.first, func.second);
    }
  }

  return true;
}