mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
Make UriParser to support [$HOSTNAME] notation.
http://reviews.llvm.org/D12025 llvm-svn: 245639
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
#endif
|
||||
|
||||
// C++ Includes
|
||||
#include <sstream>
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#if defined(__APPLE__)
|
||||
@@ -47,6 +49,8 @@
|
||||
#include "lldb/Host/Socket.h"
|
||||
#include "lldb/Interpreter/Args.h"
|
||||
|
||||
#include "Utility/UriParser.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
@@ -169,10 +173,16 @@ ConnectionFileDescriptor::Connect(const char *s, Error *error_ptr)
|
||||
else if (strstr(s, "adb://") == s)
|
||||
{
|
||||
int port = -1;
|
||||
sscanf(s, "adb://%*[^:]:%d", &port);
|
||||
char host_and_port[sizeof("localhost:65535")];
|
||||
snprintf(host_and_port, sizeof(host_and_port), "localhost:%d", port);
|
||||
return ConnectTCP(host_and_port, error_ptr);
|
||||
std::string scheme, host, path;
|
||||
if (!UriParser::Parse(s, scheme, host, port, path))
|
||||
{
|
||||
if (error_ptr)
|
||||
error_ptr->SetErrorStringWithFormat("Failed to parse URL '%s'", s);
|
||||
return eConnectionStatusError;
|
||||
}
|
||||
std::ostringstream host_and_port;
|
||||
host_and_port << "localhost:" << port;
|
||||
return ConnectTCP(host_and_port.str().c_str(), error_ptr);
|
||||
}
|
||||
else if (strstr(s, "connect://") == s)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "PlatformAndroidRemoteGDBServer.h"
|
||||
#include "Utility/UriParser.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace platform_android;
|
||||
@@ -135,3 +137,19 @@ PlatformAndroidRemoteGDBServer::DeleteForwardPort (lldb::pid_t pid)
|
||||
}
|
||||
m_port_forwards.erase(it);
|
||||
}
|
||||
|
||||
std::string
|
||||
PlatformAndroidRemoteGDBServer::MakeServerUrl(const char* scheme,
|
||||
const char* hostname,
|
||||
uint16_t port)
|
||||
{
|
||||
std::ostringstream hostname_str;
|
||||
if (!strcmp(scheme, "adb"))
|
||||
hostname_str << "[" << hostname << "]";
|
||||
else
|
||||
hostname_str << hostname;
|
||||
|
||||
return PlatformRemoteGDBServer::MakeServerUrl(scheme,
|
||||
hostname_str.str().c_str(),
|
||||
port);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,11 @@ protected:
|
||||
void
|
||||
DeleteForwardPort (lldb::pid_t pid);
|
||||
|
||||
std::string
|
||||
MakeServerUrl(const char* scheme,
|
||||
const char* hostname,
|
||||
uint16_t port) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformAndroidRemoteGDBServer);
|
||||
|
||||
|
||||
@@ -40,23 +40,6 @@ using namespace lldb_private::platform_gdb_server;
|
||||
|
||||
static bool g_initialized = false;
|
||||
|
||||
static std::string MakeGdbServerUrl(
|
||||
const std::string &platform_scheme,
|
||||
const std::string &platform_hostname,
|
||||
uint16_t port)
|
||||
{
|
||||
const char *override_scheme = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
|
||||
const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
|
||||
const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
|
||||
int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
|
||||
StreamString result;
|
||||
result.Printf("%s://%s:%u",
|
||||
override_scheme ? override_scheme : platform_scheme.c_str(),
|
||||
override_hostname ? override_hostname : platform_hostname.c_str(),
|
||||
port + port_offset);
|
||||
return result.GetString();
|
||||
}
|
||||
|
||||
void
|
||||
PlatformRemoteGDBServer::Initialize ()
|
||||
{
|
||||
@@ -969,3 +952,28 @@ PlatformRemoteGDBServer::GetRemoteUnixSignals()
|
||||
|
||||
return m_remote_signals_sp;
|
||||
}
|
||||
|
||||
std::string
|
||||
PlatformRemoteGDBServer::MakeGdbServerUrl(const std::string &platform_scheme,
|
||||
const std::string &platform_hostname,
|
||||
uint16_t port)
|
||||
{
|
||||
const char *override_scheme = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_SCHEME");
|
||||
const char *override_hostname = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_HOSTNAME");
|
||||
const char *port_offset_c_str = getenv("LLDB_PLATFORM_REMOTE_GDB_SERVER_PORT_OFFSET");
|
||||
int port_offset = port_offset_c_str ? ::atoi(port_offset_c_str) : 0;
|
||||
|
||||
return MakeServerUrl(override_scheme ? override_scheme : platform_scheme.c_str(),
|
||||
override_hostname ? override_hostname : platform_hostname.c_str(),
|
||||
port + port_offset);
|
||||
}
|
||||
|
||||
std::string
|
||||
PlatformRemoteGDBServer::MakeServerUrl(const char* scheme,
|
||||
const char* hostname,
|
||||
uint16_t port)
|
||||
{
|
||||
StreamString result;
|
||||
result.Printf("%s://%s:%u", scheme, hostname, port);
|
||||
return result.GetString();
|
||||
}
|
||||
|
||||
@@ -234,7 +234,17 @@ protected:
|
||||
virtual bool
|
||||
KillSpawnedProcess (lldb::pid_t pid);
|
||||
|
||||
virtual std::string
|
||||
MakeServerUrl(const char* scheme,
|
||||
const char* hostname,
|
||||
uint16_t port);
|
||||
|
||||
private:
|
||||
std::string
|
||||
MakeGdbServerUrl(const std::string &platform_scheme,
|
||||
const std::string &platform_hostname,
|
||||
uint16_t port);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (PlatformRemoteGDBServer);
|
||||
|
||||
};
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
#include "Utility/UriParser.h"
|
||||
|
||||
// C Includes
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// C++ Includes
|
||||
#include <cstring>
|
||||
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Host/StringConvert.h"
|
||||
@@ -24,43 +24,71 @@ using namespace lldb_private;
|
||||
// UriParser::Parse
|
||||
//----------------------------------------------------------------------
|
||||
bool
|
||||
UriParser::Parse(const char* uri,
|
||||
std::string& scheme,
|
||||
std::string& hostname,
|
||||
int& port,
|
||||
std::string& path
|
||||
)
|
||||
UriParser::Parse(const std::string& uri,
|
||||
std::string& scheme,
|
||||
std::string& hostname,
|
||||
int& port,
|
||||
std::string& path)
|
||||
{
|
||||
char scheme_buf[100] = {0};
|
||||
char hostname_buf[256] = {0};
|
||||
char port_buf[11] = {0}; // 10==strlen(2^32)
|
||||
char path_buf[2049] = {'/', 0};
|
||||
|
||||
bool ok = false;
|
||||
if (4==sscanf(uri, "%99[^:/]://%255[^/:]:%10[^/]/%2047s", scheme_buf, hostname_buf, port_buf, path_buf+1)) { ok = true; }
|
||||
else if (3==sscanf(uri, "%99[^:/]://%255[^/:]:%10[^/]", scheme_buf, hostname_buf, port_buf)) { ok = true; }
|
||||
else if (3==sscanf(uri, "%99[^:/]://%255[^/]/%2047s", scheme_buf, hostname_buf, path_buf+1)) { ok = true; }
|
||||
else if (2==sscanf(uri, "%99[^:/]://%255[^/]", scheme_buf, hostname_buf)) { ok = true; }
|
||||
std::string tmp_scheme, tmp_hostname, tmp_port, tmp_path;
|
||||
|
||||
bool success = false;
|
||||
int port_tmp = -1;
|
||||
if (port_buf[0])
|
||||
static const char* kSchemeSep = "://";
|
||||
auto pos = uri.find(kSchemeSep);
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
|
||||
// Extract path.
|
||||
tmp_scheme = uri.substr(0, pos);
|
||||
auto host_pos = pos + strlen(kSchemeSep);
|
||||
auto path_pos = uri.find_first_of("/", host_pos);
|
||||
if (path_pos != std::string::npos)
|
||||
tmp_path = uri.substr(path_pos);
|
||||
else
|
||||
tmp_path = "/";
|
||||
|
||||
auto host_port = uri.substr(
|
||||
host_pos, ((path_pos != std::string::npos) ? path_pos : uri.size()) - host_pos);
|
||||
|
||||
// Extract hostname
|
||||
if (host_port[0] == '[')
|
||||
{
|
||||
port_tmp = StringConvert::ToUInt32(port_buf, UINT32_MAX, 10, &success);
|
||||
// hostname is enclosed with square brackets.
|
||||
pos = host_port.find(']');
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
|
||||
tmp_hostname = host_port.substr(1, pos - 1);
|
||||
host_port.erase(0, pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = host_port.find(':');
|
||||
tmp_hostname = host_port.substr(0, (pos != std::string::npos) ? pos : host_port.size());
|
||||
host_port.erase(0, (pos != std::string::npos) ? pos : host_port.size());
|
||||
}
|
||||
|
||||
// Extract port
|
||||
tmp_port = host_port;
|
||||
if (!tmp_port.empty())
|
||||
{
|
||||
if (tmp_port[0] != ':')
|
||||
return false;
|
||||
tmp_port = tmp_port.substr(1);
|
||||
bool success = false;
|
||||
auto port_tmp = StringConvert::ToUInt32(tmp_port.c_str(), UINT32_MAX, 10, &success);
|
||||
if (!success || port_tmp > 65535)
|
||||
{
|
||||
// there are invalid characters in port_buf
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
scheme.assign(scheme_buf);
|
||||
hostname.assign(hostname_buf);
|
||||
port = port_tmp;
|
||||
path.assign(path_buf);
|
||||
}
|
||||
return ok;
|
||||
else
|
||||
port = -1;
|
||||
|
||||
scheme = tmp_scheme;
|
||||
hostname = tmp_hostname;
|
||||
path = tmp_path;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@ public:
|
||||
//
|
||||
// if the url is invalid, function returns false and
|
||||
// output parameters remain unchanged
|
||||
static bool Parse(const char* uri,
|
||||
std::string& scheme,
|
||||
std::string& hostname,
|
||||
int& port,
|
||||
std::string& path
|
||||
);
|
||||
static bool
|
||||
Parse(const std::string& uri,
|
||||
std::string& scheme,
|
||||
std::string& hostname,
|
||||
int& port,
|
||||
std::string& path);
|
||||
};
|
||||
|
||||
#endif // utility_UriParser_h_
|
||||
|
||||
@@ -79,12 +79,36 @@ TEST_F (UriParserTest, MinimalPortPath)
|
||||
VALIDATE
|
||||
}
|
||||
|
||||
TEST_F (UriParserTest, LongPath)
|
||||
{
|
||||
const UriTestCase testCase("x://y/abc/def/xyz", "x", "y", -1, "/abc/def/xyz");
|
||||
VALIDATE
|
||||
}
|
||||
|
||||
TEST_F (UriParserTest, TypicalPortPath)
|
||||
{
|
||||
const UriTestCase testCase("connect://192.168.100.132:5432/", "connect", "192.168.100.132", 5432, "/");
|
||||
VALIDATE
|
||||
}
|
||||
|
||||
TEST_F (UriParserTest, BracketedHostnamePort)
|
||||
{
|
||||
const UriTestCase testCase("connect://[192.168.100.132]:5432/", "connect", "192.168.100.132", 5432, "/");
|
||||
VALIDATE
|
||||
}
|
||||
|
||||
TEST_F (UriParserTest, BracketedHostname)
|
||||
{
|
||||
const UriTestCase testCase("connect://[192.168.100.132]", "connect", "192.168.100.132", -1, "/");
|
||||
VALIDATE
|
||||
}
|
||||
|
||||
TEST_F (UriParserTest, BracketedHostnameWithColon)
|
||||
{
|
||||
const UriTestCase testCase("connect://[192.168.100.132:5555]:1234", "connect", "192.168.100.132:5555", 1234, "/");
|
||||
VALIDATE
|
||||
}
|
||||
|
||||
TEST_F (UriParserTest, SchemeHostSeparator)
|
||||
{
|
||||
const UriTestCase testCase("x:/y");
|
||||
|
||||
Reference in New Issue
Block a user