www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - LDC 0.12.0 has been released

reply David Nadlinger <code klickverbot.at> writes:
Hi everyone,

The new LDC release 0.12.0 is here! Based on the 2.063.2 front-end and
LLVM 3.1-3.3 (OS X: LLVM 3.2 only), it offers all the usual features,
with a number of bug fixes and several improvements concerning
optimizations and platform support.

Please refer to the GitHub release page for the change log and the
package download links:
https://github.com/ldc-developers/ldc/releases/tag/v0.12.0

MD5 checksums for the release packages:

1e5def0a8baf7147c14c4804f1c5c7b8  ldc2-0.12.0-linux-x86.tar.gz
3a676eda121b2ec24b17834d9e0a9b09  ldc2-0.12.0-linux-x86.tar.xz
a01a12a56a7c0aa47b9ca4ee8d726eac  ldc2-0.12.0-linux-x86_64.tar.gz
dd7df5d63755f6813f0ff980921e255a  ldc2-0.12.0-linux-x86_64.tar.xz
244d52f3c4e03dc2ed5d84940aaa04ab  ldc2-0.12.0-mingw-x86.7z
87fc4bf30ccc05f0e699c4fff81c8128  ldc2-0.12.0-mingw-x86.zip
7ac8d80dce4a7a794550b3b01c04773f  ldc2-0.12.0-osx-x86_64.tar.gz
ee2ffbe871d9ff8dd94b4e95c90014f0  ldc2-0.12.0-osx-x86_64.tar.gz
b6c11ce38f405fd44b68e1d3839c739f  ldc-0.12.0-src.tar.gz

(Unlike for the beta packages, the -src suffix is now again included
in the name of the source package as it was for the previous
releases.)

As always, the Win32/MinGW packages require a recent version of the
mingw-w64 toolchain, see the (new) README file for details. There are
no packages for the Win64/MSVC port yet.

Please be sure to report any bugs at
https://github.com/ldc-developers/ldc/issues, and feel free to drop by
at the digitalmars.D.ldc forums
(http://forum.dlang.org/group/digitalmars.D.ldc) for any questions or
comments.

Thanks to everybody involved in making this happen!

Cheers,
David
Oct 22 2013
next sibling parent "David Eagen" <davideagen mailinator.com> writes:
Great news! Thanks for all the work you and the others involved 
put into this.
Oct 22 2013
prev sibling next sibling parent "nazriel" <spam dzfl.pl> writes:
On Tuesday, 22 October 2013 at 22:32:45 UTC, David Nadlinger 
wrote:
 Hi everyone,

 The new LDC release 0.12.0 is here! Based on the 2.063.2 
 front-end and
 LLVM 3.1-3.3 (OS X: LLVM 3.2 only), it offers all the usual 
 features,
 with a number of bug fixes and several improvements concerning
 optimizations and platform support.

 Please refer to the GitHub release page for the change log and 
 the
 package download links:
 https://github.com/ldc-developers/ldc/releases/tag/v0.12.0

 MD5 checksums for the release packages:

 1e5def0a8baf7147c14c4804f1c5c7b8  ldc2-0.12.0-linux-x86.tar.gz
 3a676eda121b2ec24b17834d9e0a9b09  ldc2-0.12.0-linux-x86.tar.xz
 a01a12a56a7c0aa47b9ca4ee8d726eac  
 ldc2-0.12.0-linux-x86_64.tar.gz
 dd7df5d63755f6813f0ff980921e255a  
 ldc2-0.12.0-linux-x86_64.tar.xz
 244d52f3c4e03dc2ed5d84940aaa04ab  ldc2-0.12.0-mingw-x86.7z
 87fc4bf30ccc05f0e699c4fff81c8128  ldc2-0.12.0-mingw-x86.zip
 7ac8d80dce4a7a794550b3b01c04773f  ldc2-0.12.0-osx-x86_64.tar.gz
 ee2ffbe871d9ff8dd94b4e95c90014f0  ldc2-0.12.0-osx-x86_64.tar.gz
 b6c11ce38f405fd44b68e1d3839c739f  ldc-0.12.0-src.tar.gz

 (Unlike for the beta packages, the -src suffix is now again 
 included
 in the name of the source package as it was for the previous
 releases.)

 As always, the Win32/MinGW packages require a recent version of 
 the
 mingw-w64 toolchain, see the (new) README file for details. 
 There are
 no packages for the Win64/MSVC port yet.

 Please be sure to report any bugs at
 https://github.com/ldc-developers/ldc/issues, and feel free to 
 drop by
 at the digitalmars.D.ldc forums
 (http://forum.dlang.org/group/digitalmars.D.ldc) for any 
 questions or
 comments.

 Thanks to everybody involved in making this happen!

 Cheers,
 David
Great news! Dpaste is already using it! http://dpaste.dzfl.pl/3ee6bf13
Oct 22 2013
prev sibling next sibling parent reply "simendsjo" <simendsjo gmail.com> writes:
On Tuesday, 22 October 2013 at 22:32:45 UTC, David Nadlinger 
wrote:
 Hi everyone,

 The new LDC release 0.12.0 is here! Based on the 2.063.2 
 front-end
(...) I tried it on some code, and get some strange results.. My code doesn't compile on dmd 2.063.2, but it does with ldc - how is this possible? The failure that triggers dmd was the change from (T!A).stringof == "T!A" to "T!(A)" for single param templates. I cannot find the bug-report right now though.. Another issue is build times. I know dmd should be faster, but 4x faster..? $ time dub build --build=unittest --compiler=dmd 3.48s user 0.45s system 99% cpu 3.941 total $ time dub build --build=unittest --compiler=ldc2 12.07s user 0.37s system 99% cpu 12.446 total And the resulting binary just hangs and doesn't use any resources. It gets into the main method, but somewhere it just stops. How can I help locate the error?
Oct 23 2013
next sibling parent "simendsjo" <simendsjo gmail.com> writes:
On Wednesday, 23 October 2013 at 13:46:23 UTC, simendsjo wrote:
(...)
 And the resulting binary just hangs and doesn't use any 
 resources.
 It gets into the main method, but somewhere it just stops.
(...) Should be noted that this uses vibe.ds main and I only have an empty "main" method myself.
Oct 23 2013
prev sibling parent reply David Nadlinger <code klickverbot.at> writes:
On Wed, Oct 23, 2013 at 3:46 PM, simendsjo <simendsjo gmail.com> wrote:
 My code doesn't compile on dmd 2.063.2, but it does with ldc - how is this
 possible?
There are two possible reasons for this: First, while the frontend we use is reasonably close to the upstream DMD version (and work is going on to get it even closer), there are still quite a few areas where LDC handles things differently. Second (but what I gathered from your reference to .stringof, that doesn't seem to be the case here), not all errors are actually emitted in the frontend as they should. In some (relatively rare) cases, it can be that our glue code can actually generate code for something that DMD can't handle. Usually, this would rather be things like mixing exception handling and alloca(), etc.
 Another issue is build times. I know dmd should be faster, but 4x faster..?
Well, DMD is quite heavily optimized for speed, while there has been hardly done any work on that front for LDC at all. 4x seems to be a bit excessive indeed (at least for an unoptimized build), so might be time for somebody to sit down with a profiler. ;)
 And the resulting binary just hangs and doesn't use any resources.
 It gets into the main method, but somewhere it just stops.

 How can I help locate the error?
With "somewhere it just stops", you are referring to hanging instead of terminating, right? The first step would then be to figure out where this actually happens. Either sprinkle your codebase with printf's, or just attach GDB to the process and press Ctrl+C. This should interrupt execution in the call that is blocking execution, allowing you to get a backtrace and thus hopefully pin down where the problem is. David
Oct 23 2013
next sibling parent reply "simendsjo" <simendsjo gmail.com> writes:
On Wednesday, 23 October 2013 at 15:41:42 UTC, David Nadlinger 
wrote:
 On Wed, Oct 23, 2013 at 3:46 PM, simendsjo 
 <simendsjo gmail.com> wrote:
 My code doesn't compile on dmd 2.063.2, but it does with ldc - 
 how is this
 possible?
There are two possible reasons for this: First, while the frontend we use is reasonably close to the upstream DMD version (and work is going on to get it even closer), there are still quite a few areas where LDC handles things differently. Second (but what I gathered from your reference to .stringof, that doesn't seem to be the case here), not all errors are actually emitted in the frontend as they should. In some (relatively rare) cases, it can be that our glue code can actually generate code for something that DMD can't handle. Usually, this would rather be things like mixing exception handling and alloca(), etc.
 Another issue is build times. I know dmd should be faster, but 
 4x faster..?
Well, DMD is quite heavily optimized for speed, while there has been hardly done any work on that front for LDC at all. 4x seems to be a bit excessive indeed (at least for an unoptimized build), so might be time for somebody to sit down with a profiler. ;)
 And the resulting binary just hangs and doesn't use any 
 resources.
 It gets into the main method, but somewhere it just stops.

 How can I help locate the error?
With "somewhere it just stops", you are referring to hanging instead of terminating, right? The first step would then be to figure out where this actually happens. Either sprinkle your codebase with printf's, or just attach GDB to the process and press Ctrl+C. This should interrupt execution in the call that is blocking execution, allowing you to get a backtrace and thus hopefully pin down where the problem is. David
This is way beyond what I'm able to make sense of... #0 0x00007ffff65149f3 in __epoll_wait_nocancel () from /usr/lib/libc.so.6 #1 0x00007ffff79b7ae3 in ?? () from /usr/lib/libevent-2.0.so.5 #2 0x00007ffff79a3660 in event_base_loop () from /usr/lib/libevent-2.0.so.5 #3 0x00000000004cc4f4 in vibe.core.drivers.libevent2.Libevent2Driver.runEventLoop() (this=0x7ffff7ec98c0) at libevent2.d:122 #4 0x00000000004d8357 in vibe.core.core.runEventLoop() () at core.d:84 #5 0x0000000000545eb8 in D main () at appmain.d:57 #6 0x0000000000646cf1 in rt.dmain2._d_run_main() () #7 0x000000000064659a in rt.dmain2._d_run_main() () #8 0x0000000000646d47 in rt.dmain2._d_run_main() () #9 0x000000000064659a in rt.dmain2._d_run_main() () #10 0x000000000064654f in _d_run_main () #11 0x0000000000646103 in main () Dump of assembler code for function __epoll_wait_nocancel: 0x00007ffff65149e9 <+0>: mov %rcx,%r10 0x00007ffff65149ec <+3>: mov $0xe8,%eax 0x00007ffff65149f1 <+8>: syscall => 0x00007ffff65149f3 <+10>: cmp $0xfffffffffffff001,%rax 0x00007ffff65149f9 <+16>: jae 0x7ffff6514a2f <epoll_wait+79> 0x00007ffff65149fb <+18>: retq End of assembler dump.
Oct 23 2013
parent David Nadlinger <code klickverbot.at> writes:
On Wed, Oct 23, 2013 at 6:53 PM, simendsjo <simendsjo gmail.com> wrote:
 #0  0x00007ffff65149f3 in __epoll_wait_nocancel () from /usr/lib/libc.so.6
 #1  0x00007ffff79b7ae3 in ?? () from /usr/lib/libevent-2.0.so.5
 #2  0x00007ffff79a3660 in event_base_loop () from /usr/lib/libevent-2.0.so.5
 #3  0x00000000004cc4f4 in
 vibe.core.drivers.libevent2.Libevent2Driver.runEventLoop()
 (this=0x7ffff7ec98c0) at libevent2.d:122
 #4  0x00000000004d8357 in vibe.core.core.runEventLoop() () at core.d:84
This suggests that vibe.d is waiting for some event to trigger, but it never does. The easiest way to get an idea about what is going on would probably be to sprinkle the code base with logging statements in the places where events are added (i.e. printf-style debugging) and compare the output with a DMD-compiled executable. Where exactly to add them depends a bit on what you expect to happen in your application, but you could of course also add them to pretty much every method in vibe.core.drivers.libevent2. David
Oct 23 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
David Nadlinger:

 Well, DMD is quite heavily optimized for speed, while there has 
 been hardly done any work on that front for LDC at all. 4x
 seems to be a bit excessive indeed (at least for an unoptimized
 build),
DMD is optimized for compilation speed of unoptimized builds. Bye, bearophile
Oct 23 2013
parent David Nadlinger <code klickverbot.at> writes:
On Wed, Oct 23, 2013 at 7:48 PM, bearophile <bearophileHUGS lycos.com> wrote:
 Well, DMD is quite heavily optimized for speed, while there has been
 hardly done any work on that front for LDC at all. 4x
 seems to be a bit excessive indeed (at least for an unoptimized
 build),
DMD is optimized for compilation speed of unoptimized builds.
Yes, but for optimized builds, it would not be very surprising if LDC was quite a bit slower, as it simply performs a lot more optimizations. You are right, even with heavy optimizations, we are probably not going to beat the DMD backend in debug build performance, but a 4x slowdown seems a bit much. David
Oct 23 2013
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
David Nadlinger:

 244d52f3c4e03dc2ed5d84940aaa04ab  ldc2-0.12.0-mingw-x86.7z
If I compile some C-looking D code using -noruntime can't LDC2 not put those runtime routine inside the binary and produce a smaller binary? ----------------------- A small test program: void main() { import core.stdc.stdio, std.math; immutable r = 11; foreach (immutable y; -r .. r + 1) { foreach (immutable x; -2 * r .. 2 * r + 1) { bool circle(in int c, in int r) pure nothrow { return r ^^ 2 >= (x / 2) ^^ 2 + (y - c) ^^ 2; } putchar(circle(-r / 2, r / 6) ? '#' : circle( r / 2, r / 6) ? '.' : circle(-r / 2, r / 2) ? '.' : circle( r / 2, r / 2) ? '#' : circle( 0, r) ? "#."[x < 0] : ' '); } '\n'.putchar; } } Compiling using ldc 0.12 with ldmd2 -O -release -inline -noboundscheck -output-s it produces (note the __d_allocmemory, dmd doesn't inline the lambda but it doesn't perform that call): __Dmain: pushl %ebp pushl %ebx pushl %edi pushl %esi subl $8, %esp movl $8, (%esp) calll __d_allocmemory movl %eax, 4(%esp) movl $-11, %edi .align 16, 0x90 LBB0_1: movl 4(%esp), %eax movl %edi, (%eax) movl $-22, %ebx .align 16, 0x90 LBB0_2: movl 4(%esp), %eax movl %ebx, 4(%eax) movl %ebx, %ecx shrl $31, %ecx leal (%ebx,%ecx), %edx sarl %edx imull %edx, %edx leal 5(%edi), %ebp imull %ebp, %ebp addl %edx, %ebp movl $35, %eax cmpl $2, %ebp jl LBB0_8 leal -5(%edi), %esi imull %esi, %esi addl %edx, %esi movl $46, %eax cmpl $2, %esi jl LBB0_8 cmpl $26, %ebp jl LBB0_8 cmpl $26, %esi movl $35, %eax jl LBB0_8 movl %edi, %esi imull %esi, %esi addl %edx, %esi movl $32, %eax cmpl $121, %esi jg LBB0_8 movzbl _.str(%ecx), %eax .align 16, 0x90 LBB0_8: calll __D4core4stdc5stdio7putcharFNbNeiZi incl %ebx cmpl $23, %ebx jne LBB0_2 movl $10, %eax calll __D4core4stdc5stdio7putcharFNbNeiZi incl %edi cmpl $12, %edi jne LBB0_1 xorl %eax, %eax addl $8, %esp popl %esi popl %edi popl %ebx popl %ebp ret If I replace the lambda with an inner function: void main() { import core.stdc.stdio, std.math; immutable r = 11; foreach (immutable y; -r .. r + 1) { foreach (immutable x; -2 * r .. 2 * r + 1) { bool circle(in int c, in int r) pure nothrow { return r ^^ 2 >= (x / 2) ^^ 2 + (y - c) ^^ 2; } putchar(circle(-r / 2, r / 6) ? '#' : circle( r / 2, r / 6) ? '.' : circle(-r / 2, r / 2) ? '.' : circle( r / 2, r / 2) ? '#' : circle( 0, r) ? "#."[x < 0] : ' '); } '\n'.putchar; } } Now ldc doesn't show the call to __d_allocmemory, is this expected? __Dmain: pushl %ebp pushl %ebx pushl %edi pushl %esi subl $12, %esp movl $-11, %eax .align 16, 0x90 LBB0_1: movl %eax, (%esp) movl %eax, %ecx imull %ecx, %ecx movl %ecx, 8(%esp) leal -5(%eax), %ecx imull %ecx, %ecx movl %ecx, 4(%esp) leal 5(%eax), %ebp imull %ebp, %ebp movl $-22, %esi .align 16, 0x90 LBB0_2: movl %esi, %ecx shrl $31, %ecx leal (%esi,%ecx), %edx sarl %edx imull %edx, %edx leal (%edx,%ebp), %edi movl $35, %eax cmpl $2, %edi jl LBB0_8 movl 4(%esp), %eax leal (%edx,%eax), %ebx movl $46, %eax cmpl $2, %ebx jl LBB0_8 cmpl $26, %edi jl LBB0_8 cmpl $26, %ebx movl $35, %eax jl LBB0_8 addl 8(%esp), %edx movl $32, %eax cmpl $121, %edx jg LBB0_8 movzbl _.str(%ecx), %eax .align 16, 0x90 LBB0_8: calll __D4core4stdc5stdio7putcharFNbNeiZi incl %esi cmpl $23, %esi jne LBB0_2 movl $10, %eax calll __D4core4stdc5stdio7putcharFNbNeiZi movl (%esp), %eax incl %eax cmpl $12, %eax jne LBB0_1 xorl %eax, %eax addl $12, %esp popl %esi popl %edi popl %ebx popl %ebp ret Bye, bearophile
Oct 23 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
 A small test program:


 void main() {
     import core.stdc.stdio, std.math;
     immutable r = 11;
     foreach (immutable y; -r .. r + 1) {
         foreach (immutable x; -2 * r .. 2 * r + 1) {
             bool circle(in int c, in int r) pure nothrow {
                 return r ^^ 2 >= (x / 2) ^^ 2 + (y - c) ^^ 2;
             }
             putchar(circle(-r / 2, r / 6) ? '#' :
                     circle( r / 2, r / 6) ? '.' :
                     circle(-r / 2, r / 2) ? '.' :
                     circle( r / 2, r / 2) ? '#' :
                     circle(     0, r)     ? "#."[x < 0] :
                                           ' ');
         }
         '\n'.putchar;
     }
 }
Sorry, I have copied two times the same code. That first code should be: void main() { import core.stdc.stdio, std.math; immutable r = 11; foreach (immutable y; -r .. r + 1) { foreach (immutable x; -2 * r .. 2 * r + 1) { enum circle = (in int c, in int r) pure nothrow => r ^^ 2 >= (x / 2) ^^ 2 + (y - c) ^^ 2; putchar(circle(-r / 2, r / 6) ? '#' : circle( r / 2, r / 6) ? '.' : circle(-r / 2, r / 2) ? '.' : circle( r / 2, r / 2) ? '#' : circle( 0, r) ? "#."[x < 0] : ' '); } '\n'.putchar; } } Bye, bearophile
Oct 23 2013
prev sibling next sibling parent reply David Nadlinger <code klickverbot.at> writes:
On Wed, Oct 23, 2013 at 8:40 PM, bearophile <bearophileHUGS lycos.com> wrot=
e:
 If I compile some C-looking D code using -noruntime can't LDC2 not put th=
ose
 runtime routine inside the binary and produce a smaller binary?

 -----------------------

 A small test program:


 void main() {
     import core.stdc.stdio, std.math;
     immutable r =3D 11;
     foreach (immutable y; -r .. r + 1) {
         foreach (immutable x; -2 * r .. 2 * r + 1) {
             bool circle(in int c, in int r) pure nothrow {
                 return r ^^ 2 >=3D (x / 2) ^^ 2 + (y - c) ^^ 2;
             }
             putchar(circle(-r / 2, r / 6) ? '#' :
                     circle( r / 2, r / 6) ? '.' :
                     circle(-r / 2, r / 2) ? '.' :
                     circle( r / 2, r / 2) ? '#' :
                     circle(     0, r)     ? "#."[x < 0] :
                                           ' ');
         }
         '\n'.putchar;
     }
 }
This program shouldn't even need to pull in std.math with LDC (we don't follow DMD w.r.t. the wonky requirement of importing std.math to use ^^). And indeed, if you remove the std.math import, no Phobos modules are pulled in.
 Compiling using ldc 0.12 with ldmd2 -O -release -inline -noboundscheck
 -output-s it produces (note the __d_allocmemory, dmd doesn't inline the
 lambda but it doesn't perform that call):
You are right, it shouldn't even allocate the lambda in the first place, but even if it did, one of the optimization passes should actually promote the allocation to the stack. Investigating=E2=80=A6 David
Oct 23 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
David Nadlinger:

 You are right, it shouldn't even allocate the lambda in the 
 first
 place, but even if it did, one of the optimization passes should
 actually promote the allocation to the stack. Investigating…
Please note the successive email I have written, where I have fixed a mistake. I have copied two times the same code. The code with the __d_allocmemory is the one with: enum circle = (in int c, in int r) pure nothrow => r ^^ 2 >= (x / 2) ^^ 2 + (y - c) ^^ 2; Bye, bearophile
Oct 23 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
David Nadlinger:

 This program shouldn't even need to pull in std.math with LDC 
 (we
 don't follow DMD w.r.t. the wonky requirement of importing 
 std.math to
 use ^^).
D code must be written to work on both DMD and LDC as much as humanly possible, so I'll not use that nice feature of LDC, and I hope others will do the same :-( Bye, bearophile
Oct 23 2013
parent David Nadlinger <code klickverbot.at> writes:
On Wed, Oct 23, 2013 at 9:30 PM, bearophile <bearophileHUGS lycos.com> wrote:
 D code must be written to work on both DMD and LDC as much as humanly
 possible, so I'll not use that nice feature of LDC, and I hope others will
 do the same :-(
Yes, of course. I just meant that there is definitely something strange going on (i.e. LDC emits code it wouldn't need to), as importing std.math isn't actually needed. So, there really shouldn't be any reason for Phobos code to end up in the executable even if you add the extra import, i.e. this is definitely a bug in LDC. Could you add the program to the GitHub tracker (just post it as a whole, mentioning that no symbols from std.math should be pulled in)? If you do it yourself, you'll get a notification as soon as the bug is fixed. Thanks, David
Oct 23 2013
prev sibling parent "David Nadlinger" <code klickverbot.at> writes:
On Wednesday, 23 October 2013 at 18:40:33 UTC, bearophile wrote:
 Now ldc doesn't show the call to __d_allocmemory, is this 
 expected?
With this patch, the optimizer at least catches the unnecessary heap allocation and removes it: https://github.com/ldc-developers/ldc/pull/532 Of course, we shouldn't emit the allocation in the first place. David
Oct 27 2013
prev sibling next sibling parent reply "Michael" <pr m1xa.com> writes:
On Win32 I got a error

D:/Dev/ldc/bin/../lib/libphobos-ldc.a(demangle.obj):fake:(.text+0xa9b): 
undefine
d reference to `__mingw_strtold'

What I need to do?
Oct 23 2013
parent reply David Nadlinger <code klickverbot.at> writes:
On Wed, Oct 23, 2013 at 8:59 PM, Michael <pr m1xa.com> wrote:
 On Win32 I got a error

 D:/Dev/ldc/bin/../lib/libphobos-ldc.a(demangle.obj):fake:(.text+0xa9b):
 undefine
 d reference to `__mingw_strtold'

 What I need to do?
Are you using a recent version of mingw-w64, as indicated in the release notes and the README? If so, which one? __mingw_strtold should be available in the MinGW C runtime. David
Oct 23 2013
parent "Michael" <pr m1xa.com> writes:
Thanks David,

just updated mingw64 )
Oct 23 2013
prev sibling parent reply "Michael" <pr m1xa.com> writes:
What news about Win64/MSVC port?)
Oct 23 2013
parent reply "Kai Nacke" <kai redstar.de> writes:
On Wednesday, 23 October 2013 at 20:25:17 UTC, Michael wrote:
 What news about Win64/MSVC port?)
In short, my exception handling implementation is blocked by PR16779 (http://llvm.org/bugs/show_bug.cgi?id=16779). I first need to solve this before there is a chance to commit my implementation to LLVM repo. Unfortunately this problem prevents successful compilation of Phobos right now. The good news is that I am still working on this. Regards Kai
Oct 23 2013
parent "Michael" <pr m1xa.com> writes:
 The good news is that I am still working on this.

 Regards
 Kai
You are doing good thing! Keep going ;)
Oct 24 2013