Changeset 1156
- Timestamp:
- 05/05/08 06:59:49 (2 months ago)
- Files:
-
- trunk/descent.unittest/flute/src/cn (added)
- trunk/descent.unittest/flute/src/cn/kuehne (added)
- trunk/descent.unittest/flute/src/cn/kuehne/flectioned.d (added)
- trunk/descent.unittest/flute/src/org/dsource/descent/flute/flute-old.d (added)
- trunk/descent.unittest/flute/src/org/dsource/descent/flute/flute.d (modified) (20 diffs)
- trunk/descent.unittest/flute/src/org/dsource/descent/flute/io.d (modified) (5 diffs)
- trunk/descent.unittest/flute/src/org/dsource/descent/flute/reflect.d (deleted)
- trunk/descent.unittest/flute/src/org/dsource/descent/flute/shared.d (deleted)
- trunk/descent.unittest/src/descent/internal/unittest/ui/OpenModuleAction.java (modified) (2 diffs)
- trunk/descent.unittest/testdata/src/cmdline.bat (deleted)
- trunk/descent.unittest/testdata/src/compile.bat (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/descent.unittest/flute/src/org/dsource/descent/flute/flute.d
r1113 r1156 276 276 */ 277 277 278 279 // Functions this program uses in a tango/phobos independent manner280 281 /**282 * Initializes input/output. Should be called before any IO operations are283 * performed.284 */285 //private void initIO();286 287 /**288 * Closes input/output. Should be called before program termination and after289 * initIO().290 */291 //private void closeIO();292 293 /**294 * Flushes the output stream. Should be called before waiting for user input and295 * before possibly lengthy operations to alert users.296 */297 //private void flush();298 299 /**300 * Prints the given string to the output (either a socket or stdout).301 *302 * Params:303 * str = The string to print304 */305 //private void write(char[] str);306 307 /**308 * Reads a line (terminated by a system-specific line specifier for stdout, or a309 * CRLF for socket input), and returns the line.310 *311 * Returns: The next line from the input stream312 */313 //private char[] readln();314 315 /**316 * Initalize libraries needed to lookup file/line information in exception stack317 * traces.318 */319 //private void initDebugInfo();320 321 /**322 * Close librries needed to lookup file/line information in exception stack traces.323 */324 //private void closeDebugInfo();325 326 /**327 * Attempts to look up the file/line in the debug info given an execution328 * address.329 *330 * Params:331 * addr = the execution address to look up332 * line = the line thatn was executing333 * file = the file that was executing, as reported by the debug info334 * Returns: true if and only if the lookup was succesful, false otherwise.335 */336 //private static bool getDebugInfo(void* addr, out int line, out char[] file)337 338 278 import cn.kuehne.flectioned; 339 340 /** 341 * Port to listen on (this should be configurable somehow)... 342 */ 343 private const ushort PORT = 30587; 344 345 static if(is(typeof((new object.Object()).toUtf8()) == char[])) 279 import org.dsource.descent.flute.io; 280 281 // Import and define functions for library-independent use 282 version(Tango) 346 283 { 347 284 version = inTango; … … 353 290 import tango.stdc.ctype : isdigit; 354 291 355 version(FluteCommandLine)356 {357 import tango.io.Stdout : Cin, Cout;358 }359 else360 {361 import tango.net.ServerSocket;362 import tango.net.InternetAddress;363 import tango.net.SocketConduit;364 365 import tango.io.model.IConduit;366 import tango.io.model.IBuffer;367 import tango.io.protocol.model.IWriter;368 369 import tango.io.Buffer;370 import tango.io.protocol.Writer;371 }372 373 292 static import tango.text.convert.Integer; 374 293 static if(is(typeof(tango.text.convert.Integer.toString))) … … 376 295 else 377 296 alias tango.text.convert.Integer.toUtf8 itoa; 378 379 version(FluteCommandLine) {} else 380 { 381 private ServerSocket serv; 382 private IConduit socket; 383 private IBuffer buf; 384 private IWriter writer; 385 } 386 387 private void initIO() 388 { 389 version(FluteCommandLine) 390 { } // Nothing to do 391 else 392 { 393 serv = new ServerSocket(new InternetAddress("127.0.0.1", PORT)); 394 socket = serv.accept(); 395 buf = new Buffer(socket); 396 writer = new Writer(buf); 397 } 398 } 399 400 private void closeIO() 401 { 402 version(FluteCommandLine) 403 { } // Nothing to do 404 else 405 { 406 socket.detach(); 407 serv.socket.detach(); 408 } 409 } 410 411 private void flush() 412 { 413 version(FluteCommandLine) 414 Cout.flush(); 415 else 416 writer.flush(); 417 } 418 419 private void write(char[] str) 420 { 421 version(FluteCommandLine) 422 Cout(str); 423 else 424 writer.put(str); 425 } 426 427 private char[] readln() 428 { 429 version(FluteCommandLine) 430 { 431 return Cin.copyln(); 432 } 433 else 434 { 435 char[] content; 436 437 uint line (void[] input) 438 { 439 char[] text = cast(char[]) input; 440 foreach (i, c; text) 441 { 442 if (c == '\n') 443 { 444 uint j = i; 445 if (j && (text[j - 1] == '\r')) 446 --j; 447 content = text [0 .. j]; 448 return i + 1; 449 } 450 } 451 return IConduit.Eof; 452 } 453 454 bool read = buf.next(&line) || (content = cast(char[]) 455 buf.slice(buf.readable), false); 456 return read ? content.dup : null; 457 } 458 } 459 297 460 298 private int find(char[] haystack, char[] needle) 461 299 { … … 474 312 import std.asserterror : AssertError; 475 313 476 version(FluteCommandLine)477 {478 import std.stdio: writef, fflush, stdout;479 import std.stdio : cinReadln = readln;480 }481 else482 {483 import std.socket : Socket, TcpSocket, AddressFamily, InternetAddress,484 SocketShutdown, SocketException;485 import std.socketstream : SocketStream;486 import std.stream : Stream;487 }488 489 version(FluteCommandLine) { } else490 {491 Socket serv;492 Stream stream;493 }494 495 private void initIO()496 {497 version(FluteCommandLine)498 { } // Nothing to do499 else500 {501 try502 {503 serv = new TcpSocket(AddressFamily.INET);504 serv.bind(new InternetAddress("127.0.0.1", PORT));505 serv.listen(0);506 Socket conn = serv.accept();507 stream = new SocketStream(conn);508 }509 catch(SocketException se)510 {511 std.stdio.writefln("Couldn't create socket; error code " ~512 itoa(se.errorCode));513 exit(se.errorCode);514 }515 }516 }517 518 private void closeIO()519 {520 version(FluteCommandLine)521 { } // Nothing to do522 else523 {524 stream.close();525 serv.shutdown(SocketShutdown.BOTH);526 serv.close();527 }528 }529 530 private void flush()531 {532 version(FluteCommandLine)533 fflush(stdout);534 else535 stream.flush();536 }537 538 private void write(char[] str)539 {540 version(FluteCommandLine)541 writef(str);542 else543 stream.writeString(str);544 }545 546 private char[] readln()547 {548 version(FluteCommandLine)549 return cinReadln();550 else551 return stream.readLine();552 }553 554 314 private char[] itoa(int i) 555 315 { 556 316 return format("%d", i); 557 317 } 558 }559 560 version(Windows)561 {562 /// Can we lookup debug info?563 private bool debugInfo = false;564 565 import std.c.windows.windows;566 567 private enum568 {569 MAX_MODULE_NAME32 = 255,570 TH32CS_SNAPMODULE = 0x00000008,571 SYMOPT_LOAD_LINES = 0x10,572 }573 574 private extern(Windows) struct MODULEENTRY32575 {576 DWORD dwSize;577 DWORD th32ModuleID;578 DWORD th32ProcessID;579 DWORD GlblcntUsage;580 DWORD ProccntUsage;581 BYTE *modBaseAddr;582 DWORD modBaseSize;583 HMODULE hModule;584 char szModule[MAX_MODULE_NAME32 + 1];585 char szExePath[MAX_PATH];586 }587 588 private extern(Windows) struct IMAGEHLP_LINE589 {590 DWORD SizeOfStruct;591 PVOID Key;592 DWORD LineNumber;593 PTSTR FileName;594 DWORD Address;595 }596 alias IMAGEHLP_LINE* PIMAGEHLP_LINE;597 598 private extern(Windows) BOOL Module32First(HANDLE, MODULEENTRY32*);599 private extern(Windows) BOOL Module32Next(HANDLE, MODULEENTRY32*);600 private extern(Windows) HANDLE CreateToolhelp32Snapshot(DWORD,DWORD);601 602 private HMODULE imagehlp;603 private HANDLE proc;604 private extern(Windows) DWORD function(DWORD) SymSetOptions;605 private extern(Windows) BOOL function(HANDLE, PCSTR, BOOL) SymInitialize;606 private extern(Windows) BOOL function(HANDLE) SymCleanup;607 private extern(Windows) DWORD function(HANDLE, HANDLE, PCSTR, PCSTR, DWORD, DWORD) SymLoadModule;608 private extern(Windows) BOOL function(HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE) SymGetLineFromAddr;609 610 private void initDebugInfo()611 {612 MODULEENTRY32 moduleEntry;613 moduleEntry.dwSize = moduleEntry.sizeof;614 char buffer[4096];615 616 try617 {618 scope(failure)619 {620 if(imagehlp)621 FreeLibrary(imagehlp);622 623 SymSetOptions = null;624 SymInitialize = null;625 SymCleanup = null;626 SymLoadModule = null;627 SymGetLineFromAddr = null;628 }629 630 proc = GetCurrentProcess();631 if(!proc)632 throw new Exception("GetCurrentProcess() returned null");633 634 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);635 if(!snapshot)636 throw new Exception("CreateToolHelp32Snapshot failed");637 638 imagehlp = LoadLibraryA("imagehlp.dll");639 if(!imagehlp)640 throw new Exception("Failed to load imagehlp.dll");641 642 SymSetOptions = cast(typeof(SymSetOptions)) GetProcAddress(imagehlp, "SymSetOptions");643 if(!SymSetOptions)644 throw new Exception("Failed to load SymSetOptions");645 646 SymInitialize = cast(typeof(SymInitialize)) GetProcAddress(imagehlp, "SymInitialize");647 if(!SymInitialize)648 throw new Exception("Failed to load SymInitialize");649 650 SymCleanup = cast(typeof(SymCleanup)) GetProcAddress(imagehlp, "SymCleanup");651 if(!SymCleanup)652 throw new Exception("Failed to load SymCleanup");653 654 SymLoadModule = cast(typeof(SymLoadModule)) GetProcAddress(imagehlp, "SymLoadModule");655 if(!SymLoadModule)656 throw new Exception("Failed to load SymLoadModule");657 658 SymGetLineFromAddr = cast(typeof(SymGetLineFromAddr)) GetProcAddress(imagehlp, "SymGetLineFromAddr");659 if(!SymGetLineFromAddr)660 throw new Exception("Failed to load SymGetLineFromAddr");661 662 // Since Flectioned doesn't load the line inforamtion when loading663 // symbols, we have little choice but to load all the symbols again, this664 // time with SYMOPT_LOAD_LINES on.665 if(!SymCleanup(proc))666 throw new Exception("SymCleanup failed");667 SymSetOptions(SYMOPT_LOAD_LINES);668 if(!SymInitialize(proc, null, FALSE))669 throw new Exception("SymInitialize failed");670 671 // We have to enumerate through the modules individually so that each672 // module finds its search path673 if(!Module32First(snapshot, &moduleEntry))674 throw new Exception("Module32First Failed");675 do676 {677 if(GetModuleFileNameA(moduleEntry.hModule, buffer.ptr, buffer.length))678 SymLoadModule(proc, HANDLE.init, buffer.ptr, null, 0, 0);679 }680 while(Module32Next(snapshot, &moduleEntry));681 682 debugInfo = true;683 }684 catch(Exception e)685 {686 //write(e.toString() ~ "\n");687 }688 }689 690 private void closeDebugInfo()691 {692 if(debugInfo)693 {694 SymCleanup(proc);695 FreeLibrary(imagehlp);696 697 SymSetOptions = null;698 SymInitialize = null;699 SymCleanup = null;700 SymLoadModule = null;701 SymGetLineFromAddr = null;702 }703 }704 705 private bool getDebugInfo(void* addr, out int line, out char[] file)706 {707 if(!debugInfo || !addr)708 goto Lunknown;709 710 IMAGEHLP_LINE lineInfo;711 DWORD displacement;712 lineInfo.SizeOfStruct = lineInfo.sizeof;713 714 if(!SymGetLineFromAddr(proc, cast(DWORD) addr, &displacement, &lineInfo))715 goto Lunknown;716 717 line = lineInfo.LineNumber;718 file = lineInfo.FileName[0 .. strlen(lineInfo.FileName)];719 return true;720 721 Lunknown:722 return false;723 }724 }725 else726 {727 // TODO728 318 } 729 319 … … 813 403 { 814 404 case ResultType.PASSED: 815 write("PASSED\r\n");405 io.write("PASSED\r\n"); 816 406 return; 817 407 818 408 case ResultType.FAILED: 819 write("FAILED\r\n");409 io.write("FAILED\r\n"); 820 410 version(inTango) 821 411 { … … 823 413 AssertException ae = cast(AssertException) e; 824 414 assert(ae !is null); 825 write("Assertion failed in " ~ ae.file ~ " at line " ~415 io.write("Assertion failed in " ~ ae.file ~ " at line " ~ 826 416 itoa(ae.line)); 827 417 if(ae.msg && ae.msg.length > 0) 828 write(": " ~ ae.msg);829 write("\r\n");418 io.write(": " ~ ae.msg); 419 io.write("\r\n"); 830 420 } 831 421 else … … 843 433 AssertError ae = cast(AssertError) e; 844 434 assert(ae !is null); 845 write("Assertion failed in " ~ ae.filename ~ " at line " ~435 io.write("Assertion failed in " ~ ae.filename ~ " at line " ~ 846 436 itoa(ae.linnum)); 847 437 char[] msg = extractMessage(ae.msg); 848 438 if(msg) 849 write(": " ~ msg);850 write("\r\n");439 io.write(": " ~ msg); 440 io.write("\r\n"); 851 441 } 852 442 goto LprintStackTrace; … … 855 445 // and tango, i.e. filename/line, etc. 856 446 case ResultType.ERROR: 857 write("ERROR\r\n");447 io.write("ERROR\r\n"); 858 448 static if(is(typeof((new Object).toString))) 859 write("Exception " ~ e.classinfo.name ~ ": " ~ e.toString()449 io.write("Exception " ~ e.classinfo.name ~ ": " ~ e.toString() 860 450 ~ "\r\n"); 861 451 else 862 write("Exception " ~ e.classinfo.name ~ ": " ~ e.toUtf8()452 io.write("Exception " ~ e.classinfo.name ~ ": " ~ e.toUtf8() 863 453 ~ "\r\n"); 864 454 goto LprintStackTrace; … … 906 496 int line; 907 497 char[] file; 908 if(get DebugInfo(ste.code, line, file))498 if(getLineFromAddr(ste.code, line, file)) 909 499 { 910 500 buf ~= file ~ ":" ~ itoa(line); … … 915 505 } 916 506 buf ~= ")\r\n"; 917 write(buf);507 io.write(buf); 918 508 } 919 509 } … … 1242 832 { 1243 833 case SearchResult.TestFound.NOT_FOUND: 1244 write("Test " ~ spec ~ "not found\r\n");834 io.write("Test " ~ spec ~ "not found\r\n"); 1245 835 return null; 1246 836 case SearchResult.TestFound.AMBIGUOUS: 1247 write("Simple name " ~ spec[1 .. $] ~ " is ambigous, could refer"837 io.write("Simple name " ~ spec[1 .. $] ~ " is ambigous, could refer" 1248 838 " to either " ~ found.ambig.fqns[0] ~ " or " ~ 1249 839 found.ambig.fqns[1]); … … 1291 881 foreach(spec; testNames.sort) 1292 882 { 1293 write(spec ~ "\r\n");883 io.write(spec ~ "\r\n"); 1294 884 TestResult result = runTest(spec); 1295 885 if(result) … … 1308 898 } 1309 899 } 1310 write("\r\n");1311 flush();900 io.write("\r\n"); 901 io.flush(); 1312 902 } 1313 903 1314 904 uint total = passed + failed + error; 1315 write(" PASSED: " ~ itoa(passed) ~ "/" ~ itoa(total) ~ "\r\n");1316 write(" FAILED: " ~ itoa(failed) ~ "/" ~ itoa(total) ~ "\r\n");1317 write(" ERROR: " ~ itoa(error) ~ "/" ~ itoa(total) ~ "\r\n");905 io.write(" PASSED: " ~ itoa(passed) ~ "/" ~ itoa(total) ~ "\r\n"); 906 io.write(" FAILED: " ~ itoa(failed) ~ "/" ~ itoa(total) ~ "\r\n"); 907 io.write(" ERROR: " ~ itoa(error) ~ "/" ~ itoa(total) ~ "\r\n"); 1318 908 } 1319 909 } … … 1321 911 /// The registry of all the tests in the pplication 1322 912 private TestRegistry registry; 913 914 /// The I/O provider used for all operations 915 private IOProvider io; 1323 916 1324 917 /** … … 1329 922 { 1330 923 TracedException.traceAllExceptions(); 1331 initIO(); 1332 initDebugInfo(); 1333 write(VERSION_STRING ~ "\r\n"); 924 io = getIOProvider(); 925 io.write(VERSION_STRING ~ "\r\n"); 1334 926 initRegistry(); 1335 927 if(!commandLoop()) … … 1343 935 private void fluteExit() 1344 936 { 1345 flush(); 1346 closeDebugInfo(); 1347 closeIO(); 937 io.flush(); 938 delete io; 1348 939 _moduleDtor(); 1349 940 gc_term(); … … 1367 958 { 1368 959 LnextCommand: 1369 write("(flute)\r\n");1370 flush();1371 char[] line = trim( readln());960 io.write("(flute)\r\n"); 961 io.flush(); 962 char[] line = trim(io.readln()); 1372 963 if(line.length < 1) 1373 964 goto LnextCommand; … … 1391 982 goto default; 1392 983 foreach(spec; registry.getTestNames()) 1393 write(spec ~ "\r\n");984 io.write(spec ~ "\r\n"); 1394 985 goto LnextCommand; 1395 986 … … 1411 1002 // It's an unknown command -- say so & try again 1412 1003 default: 1413 write("Unrecognized command " ~ line ~ "\r\n");1004 io.write("Unrecognized command " ~ line ~ "\r\n"); 1414 1005 goto LnextCommand; 1415 1006 } … … 1490 1081 version(Flute_NoWarnings) {} 1491 1082 else 1492 write("Warning: Test " ~ test.getSignature() ~1083 io.write("Warning: Test " ~ test.getSignature() ~ 1493 1084 " given multiple names, only " ~ test.getSimpleName()~ 1494 1085 " used\r\n"); trunk/descent.unittest/flute/src/org/dsource/descent/flute/io.d
r1150 r1156 1 /** 2 * Provides a set of (simple) library-independent I/O operations depending on 3 * what version is specified. If FluteCommandLine is specified, will provide 4 * console stdio, which is useful mainly for testing purposes. Otherwise, will 5 * provide socket I/O. 6 * 7 * The socket will always bind to the localhost, and will opn a port determined 8 * by the contents of the ".fluteio" file (without the quotes) in the current 9 * working directory. This file's sole contents should be an ASCII-encoded 10 * decimal integer between 1024 and 65535m representing the port flute should 11 * open on. If this file does not exist or is in the wrong format, an error will 12 * be printed to stdout and the application will exit. 13 */ 1 14 module org.dsource.descent.flute.io; 2 15 … … 7 20 else 8 21 { 9 import std.file : exists, read; 10 import std.stdio: writef, fflush, stdout; 22 version(FluteCommandLine) 23 { 24 import std.stdio : writef, fflush, stdout, cinReadln = readln; 25 } 26 else 27 { 28 import std.c.stdlib : exit, EXIT_SUCCESS, EXIT_FAILURE; 29 import std.ctype : isdigit; 30 import std.file : exists, read; 31 import std.socket : Socket, TcpSocket, AddressFamily, InternetAddress, 32 SocketShutdown, SocketException; 33 import std.socketstream : SocketStream; 34 import std.stdio: writef; 35 import std.stream : Stream; 36 import std.string : atoi; 37 } 11 38 } 12 39 13 private IOProvider ioProvider; 14 40 /** 41 * Gets a new instance of IO provider. This instance should be explicitly 42 * deleted when done. This should only be called once (since trying to open a 43 * socket on the same port more than once will obviously not work too well). 44 */ 15 45 public IOProvider getIOProvider() 16 46 { 17 if(null is ioProvider) 18 { 19 ioProvider = new PhobosStdioProvider(); 20 } 21 22 return ioProvider; 47 return new IOProviderImpl(); 23 48 } 24 49 25 public interface IOProvider 50 /** 51 * The interface for issuing I/O commands. This is an abstract class instead of 52 * an interface to get around the limitation in D that interfaces can't be 53 * deleted. 54 */ 55 public abstract class IOProvider 26 56 { 27 57 /** … … 31 61 * str = The string to print 32 62 */ 33 public void write(string str);63 public abstract void write(string str); 34 64 35 65 /** 36 * Flushes the output stream. Should be called before waiting for user input and37 * before possibly lengthy operations to alert users.66 * Flushes the output stream. Should be called before waiting for user input 67 * and before possibly lengthy operations to alert users. 38 68 */ 39 public void flush();69 public abstract void flush(); 40 70 41 71 /** … … 44 74 * Returns: The next line from the input stream 45 75 */ 46 public string readln(); 47 48 /** 49 * Provides a library-independent interface for accessing a file. 50 * It is assumed the file is a smallish UTF-8 text file. 51 * 52 * Returns: a new handle to the file or null if the file could not be 53 * found 54 */ 55 protected FileHandle getFileHandle(string filename); 56 } 57 58 /** 59 * Provides a library-independent interface for reading from a smallish UTF-8 60 * text file in a line-by-line manner. 61 */ 62 private interface FileHandle 63 { 64 /** 65 * Iterates over the contents of a file line-by line. 66 */ 67 public int opApply(int delegate(ref string) dg); 76 public abstract string readln(); 68 77 } 69 78 … … 74 83 else 75 84 { 76 private abstract class PhobosIOProvider : IOProvider85 version(FluteCommandLine) 77 86 { 78 pr otected final FileHandle getFileHandle(string filename)79 { 80 if(exists(filename))87 private final class IOProviderImpl : IOProvider 88 { 89 public void write(string str) 81 90 { 82 return new class(filename) FileHandle 83 { 84 private string filename; 85 86 public this(string filename) 87 { 88 this.filename = filename; 89 } 90 91 public int opApply(int delegate(ref string) dg) 92 { 93 // Read the file 94 char[] text = cast(char[]) read(filename); 95 96 // Iterate through the lines 97 uint lineStart = 0; 98 uint i = 0; 99 for(; i < test.length; i++) 100 { 101 char c = text[i]; 102 if (c == '\n') 103 { 104 uint lineEnd = i; 105 106 // Handle a \r\n 107 if(lineEnd && (text[lineEnd - 1] == '\r')) 108 lineEnd--; 109 110 char[] line = text[lineStart .. lineEnd]; 111 lineStart = i + 1; 112 113 int result = dg(line); 114 if(result) 115 return result; 116 } 117 } 118 119 // Slurp up the remainder of the text as the final line 120 if(lineStart < text.length) 121 { 122 char[] line = text[lineStart .. i]; 123 int result = dg(line); 124 if(result) 125 return result; 126 } 127 128 return 0; 129 } 130 }; 91 writef(str); 131 92 } 132 else 93 94 public void flush() 133 95 { 134 return null; 96 fflush(stdout); 97 } 98 99 public string readln() 100 { 101 return cinReadln(); 135 102 } 136 103 } 137 104 } 138 139 private final class PhobosStdioProvider : PhobosIOProvider 140 { 141 public void write(string str) 105 else 106 { 107 private final class IOProviderImpl : IOProvider 142 108 { 143 writef(str); 144 } 145 146 public void flush() 147 { 148 fflush(stdout); 149 } 150 151 public string readln() 152 { 153 return cinReadln(); 109 Socket serv; 110 Stream stream; 111 112 public this() 113 { 114 writef("Port %s\n", getPort()); 115 exit(EXIT_SUCCESS); 116 117 try 118 { 119 serv = new TcpSocket(AddressFamily.INET); 120 serv.bind(new InternetAddress("127.0.0.1", getPort())); 121 serv.listen(0); 122 Socket conn = serv.accept(); 123 stream = new SocketStream(conn); 124 } 125 catch(SocketException se) 126 { 127 writef("Couldn't create socket; error code %d\n", 128 se.errorCode); 129 exit(se.errorCode); 130 } 131 } 132 133 public ~this() 134 { 135 try 136 { 137 stream.close(); 138 serv.shutdown(SocketShutdown.BOTH); 139 serv.close(); 140 } 141 catch(Exception e) 142 { 143 // Ignore 144 } 145 } 146 147 public void write(string str) 148 { 149 stream.writeString(str); 150 } 151 152 public void flush() 153 { 154 stream.flush(); 155 } 156 157 public string readln() 158 { 159 return stream.readLine(); 160 } 161 162 private const string CONFIG_FILE_NAME = ".fluteport"; 163 164 private uint getPort() 165 { 166 if(!exists(CONFIG_FILE_NAME)) 167 { 168 writef("Couldn't open config file %s\n", CONFIG_FILE_NAME); 169 exit(EXIT_FAILURE); 170 } 171 172 string contents = cast(string) read(CONFIG_FILE_NAME); 173 174 uint i = 0; 175 while(i < contents.length && isdigit(contents[i])) 176 i++; 177 178 if(0 == i) 179 { 180 writef("Invalid flute config file %s\n", CONFIG_FILE_NAME); 181 exit(EXIT_FAILURE); 182 } 183 184 string portStr = contents[0 .. i]; 185 int portNum = atoi(portStr); 186 187 if(portNum < 1024 || portNum > 65535) 188 { 189 writef("Invalid port %d - Must be in the range 1024 .. 65535\n", 190 portNum); 191 exit(EXIT_FAILURE); 192 } 193 194 return portNum; 195 } 154 196 } 155 197 } trunk/descent.unittest/src/descent/internal/unittest/ui/OpenModuleAction.java
r1150 r1156 11 11 import descent.core.IJavaModel; 12 12 import descent.core.IJavaProject; 13 import descent.core.IPackageFragment; 14 import descent.core.IPackageFragmentRoot; 13 15 import descent.core.JavaModelException; 14 16 import descent.internal.compiler.parser.ISignatureConstants; … … 50 52 51 53 private static ICompilationUnit findModule(IJavaProject project, 52 String moduleSignature, Set<IJavaProject> visitedProjects) 53 throws JavaModelException 54 String moduleSignature, 55 Set<IJavaProject> visitedProjects) 56 throws JavaModelException 54 57 { 55 58 if (visitedProjects.contains(project)) 56 59 return null; 57 60 58 ICompilationUnit module; 59 // TODO IJavaElement javaElement = project.findBySignature(moduleSignature); 60 IJavaElement javaElement = null; 61 if(javaElement != null && javaElement instanceof ICompilationUnit 62 && javaElement.exists()) 63 { 64 // Note: existance must be tested since an IcompilationUnit may 65 // be returned for non-existant modules 66 module = (ICompilationUnit) javaElement; 67 return module; 68 } 61 int index = moduleSignature.lastIndexOf('.'); 62 String packagePart = index > 0 ? moduleSignature.substring(0, index) : ""; 63 String modulePart = String.format("%1$s.d", index > 0 ? 64 moduleSignature.substring(index + 1) : moduleSignature); 65 66 ICompilationUnit module = null; 67 for(IPackageFragmentRoot root : project.getPackageFragmentRoots()) 68 { 69 IPackageFragment pkg = root.getPackageFragment(packagePart); 70 if (pkg.exists())&n
