static fbstring unescapeString(fbstring val) { fbstring s = ""; for (int i = 0; i < val.size(); ) { int ch = val[i++]; if (ch == '\\') { if (i == val.size()) { throw std::logic_error( folly::format("Malformed string: '{0}'", val).str()); } ch = val[i++]; switch (ch) { case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; case '/': case '"': case '\'': case '\\':break; case '0': ch = 0; if (i == val.size() || (!isdigit(val[i]) && val[i] != 'x' && val[i] != 'X')) { break; } // fall through default: throw std::logic_error( folly::format("Malformed string: '{0}'", val).str()); break; } } s += (char)ch; } return s; }
static fbstring genDocCommentPreamble(const fbstring& name, const fbstring& desc, long flags, const fbstring& classname) { fbstring ret; if (flags & HipHopSpecific) { ret = "( HipHop specific )"; } else { ret = "( excerpt from http://php.net/manual/en/"; if (classname.size()) { ret += classname + "."; } else { ret += "function."; } auto mangled_name = name; for (auto it = mangled_name.begin(); it != mangled_name.end(); ++it) { if (*it == '_') { *it = '-'; } } ret += mangled_name + ".php )"; } if (desc.size()) { ret += "\n" + desc; } return ret + "\n\n"; }
/* * Strip an idl name of any namespaces. */ static fbstring toCppName(fbstring idlName) { fbstring cppName; size_t endNs = idlName.find_last_of(NAMESPACE_STRING); cppName = (std::string::npos == endNs) ? idlName : idlName.substr(endNs + 1); assert(!cppName.empty()); return cppName; }
static fbstring formatDocComment(const fbstring& comment) { const char *p = comment.c_str(); const char *s; const char *e = p + comment.size(); fbstring ret("/**\n"); while ((s = strchr(p, '\n'))) { ret += " *"; if ((s - p) > 1) { ret += " " + fbstring(p, (s - p)); } ret += "\n"; p = s + 1; } if (p < e) { ret += " * " + fbstring(p) + "\n"; } return ret + " */"; }
static fbstring genDocCommentPreamble(const fbstring& name, const fbstring& desc, long flags, const fbstring& classname) { fbstring ret; if (flags & HipHopSpecific) { ret = "( HipHop specific )"; } else { ret = "( excerpt from http://php.net/manual/en/"; if (classname.size()) { ret += classname + "."; } else { ret += "function."; } ret += name + ".php )"; } if (desc.size()) { ret += "\n" + desc; } return ret + "\n\n"; }
PhpFunc PhpFunc::fromDynamic(const folly::dynamic& d, const fbstring& className) { // Better at least have a name auto name = d["name"].asString(); auto args = d.find("args"); auto flags = d.find("flags"); auto ret = d.find("return"); if (args == d.items().end() || !args->second.isArray()) { throw std::logic_error( folly::format("'{0}' must have an array field 'args'", name).str() ); } if (flags == d.items().end() || !flags->second.isArray()) { throw std::logic_error( folly::format("'{0}' must have an array field 'flags'", name).str() ); } if (ret == d.items().end() || !ret->second.isObject() || ret->second.find("type") == ret->second.items().end()) { throw std::logic_error( folly::format("'{0}' must have an array field 'return', which must have " "a string field 'type'", name).str() ); } auto areVarargs = [](const fbstring& str) { return (str == "VariableArguments" || str == "RefVariableArguments" || str == "MixedVariableArguments"); }; fbvector<PhpParam> params; try { params = std::move(folly::convertTo<fbvector<PhpParam>>(args->second)); } catch (const std::exception& exc) { throw std::logic_error( folly::format("'{0}' has an arg with either 'name' or 'type' field " "missing", name).str() ); } if (name == "__get" || name == "__set" || name == "__isset" || name == "__unset" || name == "__call") { for (auto& param : params) { param.cppType = "HPHP::Variant"; } } auto refIt = d.find("ref"); bool ref = (refIt != d.items().end() && refIt->second.asString() == "true"); PhpFunc retval; retval.name = name; retval.className = className; retval.returnCppType = typeString(ret->second["type"], true); retval.returnByRef = ref; retval.params = params; retval.isVarargs = anyFlags(areVarargs, flags->second); retval.isStatic = false; if (!className.empty()) { auto areStatic = [](const fbstring& str) { return str == "IsStatic"; }; retval.isStatic = anyFlags(areStatic, flags->second); } retval.initComputedProps(); return retval; }