Merge branch 'master' of https://github.com/Hackerpilot/DCD
This commit is contained in:
commit
636e31edfb
|
@ -18,6 +18,9 @@ perf.data.old
|
|||
# Valgrind reports
|
||||
callgrind.*
|
||||
|
||||
# GDB temp files
|
||||
.gdb_history
|
||||
|
||||
# Git hash file
|
||||
githash.txt
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ dmd^
|
|||
src\client\client.d^
|
||||
src\common\messages.d^
|
||||
src\common\dcd_version.d^
|
||||
src\common\socket.d^
|
||||
msgpack-d\src\msgpack.d^
|
||||
-Imsgpack-d\src^
|
||||
-release -inline -O -wi^
|
||||
|
|
|
@ -30,13 +30,14 @@ import std.conv;
|
|||
import std.string;
|
||||
import std.experimental.logger;
|
||||
|
||||
import msgpack;
|
||||
import common.messages;
|
||||
import common.dcd_version;
|
||||
import common.socket;
|
||||
|
||||
int main(string[] args)
|
||||
{
|
||||
sharedLog.fatalHandler = () {};
|
||||
|
||||
size_t cursorPos = size_t.max;
|
||||
string[] importPaths;
|
||||
ushort port = 9166;
|
||||
|
@ -106,24 +107,12 @@ int main(string[] args)
|
|||
|
||||
if (query)
|
||||
{
|
||||
try
|
||||
if (serverIsRunning(useTCP, socketFile, port))
|
||||
{
|
||||
Socket socket = createSocket(socketFile, port);
|
||||
scope (exit) { socket.shutdown(SocketShutdown.BOTH); socket.close(); }
|
||||
request.kind = RequestKind.query;
|
||||
if (sendRequest(socket, request))
|
||||
{
|
||||
const AutocompleteResponse response = getResponse(socket);
|
||||
if (response.completionType == "ack")
|
||||
{
|
||||
writeln("Server is running");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
throw new Exception("");
|
||||
}
|
||||
writeln("Server is running");
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
else
|
||||
{
|
||||
writeln("Server is not running");
|
||||
return 1;
|
||||
|
@ -312,47 +301,26 @@ Socket createSocket(string socketFile, ushort port)
|
|||
}
|
||||
else
|
||||
{
|
||||
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
|
||||
socket.connect(new UnixAddress(socketFile));
|
||||
version(Windows)
|
||||
{
|
||||
// should never be called with non-null socketFile on Windows
|
||||
assert(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
|
||||
socket.connect(new UnixAddress(socketFile));
|
||||
}
|
||||
}
|
||||
socket.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, dur!"seconds"(5));
|
||||
socket.blocking = true;
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: true on success
|
||||
*/
|
||||
bool sendRequest(Socket socket, AutocompleteRequest request)
|
||||
{
|
||||
ubyte[] message = msgpack.pack(request);
|
||||
ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof];
|
||||
auto messageLength = message.length;
|
||||
messageBuffer[0 .. size_t.sizeof] = (cast(ubyte*) &messageLength)[0 .. size_t.sizeof];
|
||||
messageBuffer[size_t.sizeof .. $] = message[];
|
||||
return socket.send(messageBuffer) == messageBuffer.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the response from the server
|
||||
*/
|
||||
AutocompleteResponse getResponse(Socket socket)
|
||||
{
|
||||
ubyte[1024 * 16] buffer;
|
||||
auto bytesReceived = socket.receive(buffer);
|
||||
if (bytesReceived == Socket.ERROR)
|
||||
throw new Exception("Incorrect number of bytes received");
|
||||
if (bytesReceived == 0)
|
||||
throw new Exception("Server closed the connection, 0 bytes received");
|
||||
AutocompleteResponse response;
|
||||
msgpack.unpack(buffer[0..bytesReceived], response);
|
||||
return response;
|
||||
}
|
||||
|
||||
void printDocResponse(AutocompleteResponse response)
|
||||
{
|
||||
import std.array: join;
|
||||
response.docComments.join(r"\n\n").writeln;
|
||||
response.docComments.join(r"\n\n").writeln;
|
||||
}
|
||||
|
||||
void printLocationResponse(AutocompleteResponse response)
|
||||
|
|
|
@ -21,7 +21,7 @@ module common.dcd_version;
|
|||
/**
|
||||
* Human-readable version number
|
||||
*/
|
||||
enum DCD_VERSION = "v0.8.0-alpha1";
|
||||
enum DCD_VERSION = "v0.8.0-beta2";
|
||||
|
||||
version (Windows) {}
|
||||
else version (built_with_dub) {}
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
module common.messages;
|
||||
|
||||
import std.socket;
|
||||
import msgpack;
|
||||
|
||||
/**
|
||||
* The type of completion list being returned
|
||||
*/
|
||||
|
@ -157,3 +160,69 @@ struct AutocompleteResponse
|
|||
*/
|
||||
string[] importPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: true on success
|
||||
*/
|
||||
bool sendRequest(Socket socket, AutocompleteRequest request)
|
||||
{
|
||||
ubyte[] message = msgpack.pack(request);
|
||||
ubyte[] messageBuffer = new ubyte[message.length + message.length.sizeof];
|
||||
auto messageLength = message.length;
|
||||
messageBuffer[0 .. size_t.sizeof] = (cast(ubyte*) &messageLength)[0 .. size_t.sizeof];
|
||||
messageBuffer[size_t.sizeof .. $] = message[];
|
||||
return socket.send(messageBuffer) == messageBuffer.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the response from the server
|
||||
*/
|
||||
AutocompleteResponse getResponse(Socket socket)
|
||||
{
|
||||
ubyte[1024 * 16] buffer;
|
||||
auto bytesReceived = socket.receive(buffer);
|
||||
if (bytesReceived == Socket.ERROR)
|
||||
throw new Exception("Incorrect number of bytes received");
|
||||
if (bytesReceived == 0)
|
||||
throw new Exception("Server closed the connection, 0 bytes received");
|
||||
AutocompleteResponse response;
|
||||
msgpack.unpack(buffer[0..bytesReceived], response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns: true if a server instance is running
|
||||
* Params:
|
||||
* useTCP = `true` to check a TCP port, `false` for UNIX domain socket
|
||||
* socketFile = the file name for the UNIX domain socket
|
||||
* port = the TCP port
|
||||
*/
|
||||
bool serverIsRunning(bool useTCP, string socketFile, ushort port)
|
||||
{
|
||||
scope (failure)
|
||||
return false;
|
||||
AutocompleteRequest request;
|
||||
request.kind = RequestKind.query;
|
||||
Socket socket;
|
||||
scope (exit)
|
||||
{
|
||||
socket.shutdown(SocketShutdown.BOTH);
|
||||
socket.close();
|
||||
}
|
||||
if (useTCP)
|
||||
{
|
||||
socket = new TcpSocket(AddressFamily.INET);
|
||||
socket.connect(new InternetAddress("localhost", port));
|
||||
}
|
||||
else
|
||||
{
|
||||
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
|
||||
socket.connect(new UnixAddress(socketFile));
|
||||
}
|
||||
socket.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, dur!"seconds"(5));
|
||||
socket.blocking = true;
|
||||
if (sendRequest(socket, request))
|
||||
return getResponse(socket).completionType == "ack";
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -42,4 +42,8 @@ string generateSocketName()
|
|||
"dcd.socket");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ int main(string[] args)
|
|||
string socketFile = generateSocketName();
|
||||
}
|
||||
|
||||
sharedLog.fatalHandler = () {};
|
||||
|
||||
try
|
||||
{
|
||||
getopt(args, "port|p", &port, "I", &importPaths, "help|h", &help,
|
||||
|
@ -86,6 +88,8 @@ int main(string[] args)
|
|||
return 1;
|
||||
}
|
||||
|
||||
globalLogLevel = level;
|
||||
|
||||
if (printVersion)
|
||||
{
|
||||
version (Windows)
|
||||
|
@ -109,7 +113,11 @@ int main(string[] args)
|
|||
return 1;
|
||||
}
|
||||
|
||||
globalLogLevel = level;
|
||||
if (serverIsRunning(useTCP, socketFile, port))
|
||||
{
|
||||
fatal("Another instance of DCD-server is already running");
|
||||
return 1;
|
||||
}
|
||||
|
||||
info("Starting up...");
|
||||
StopWatch sw = StopWatch(AutoStart.yes);
|
||||
|
@ -128,17 +136,25 @@ int main(string[] args)
|
|||
}
|
||||
else
|
||||
{
|
||||
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
|
||||
if (exists(socketFile))
|
||||
version(Windows)
|
||||
{
|
||||
info("Cleaning up old socket file at ", socketFile);
|
||||
remove(socketFile);
|
||||
fatal("UNIX domain sockets not supported on Windows");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
|
||||
if (exists(socketFile))
|
||||
{
|
||||
info("Cleaning up old socket file at ", socketFile);
|
||||
remove(socketFile);
|
||||
}
|
||||
socket.blocking = true;
|
||||
socket.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true);
|
||||
socket.bind(new UnixAddress(socketFile));
|
||||
setAttributes(socketFile, S_IRUSR | S_IWUSR);
|
||||
info("Listening at ", socketFile);
|
||||
}
|
||||
socket.blocking = true;
|
||||
socket.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, true);
|
||||
socket.bind(new UnixAddress(socketFile));
|
||||
setAttributes(socketFile, S_IRUSR | S_IWUSR);
|
||||
info("Listening at ", socketFile);
|
||||
}
|
||||
socket.listen(0);
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
identifiers
|
||||
C l
|
||||
alignof k
|
||||
i v
|
||||
init k
|
||||
mangleof k
|
||||
sizeof k
|
||||
stringof k
|
||||
tupleof k
|
|
@ -0,0 +1,10 @@
|
|||
struct Foo(C)
|
||||
{
|
||||
int i;
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
auto foo = Foo!int();
|
||||
foo.
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
set -e
|
||||
set -u
|
||||
|
||||
../../bin/dcd-client $1 file.d -c66 > actual1.txt
|
||||
diff actual1.txt expected1.txt
|
Loading…
Reference in New Issue