Using BOM to auto-detect file encoding
I would like to know if there exists a 'stream' or 'file' class that is able to take a text file with a correct BOM, and an 'ouput' utf encoding. It want it to be capable of detecting the 'input' stream utf encoding by using the BOM, and do the encoding for me on the way out in the specified 'output' utf encoding. Right now I am using std.stream.File (which I know is going the way of all the earth soon) and manually parsing the BOM myself to then choose whether I call 'readLine' or 'readLineW', and then subsequently calling 'toUTF8' after that. It just seems like something like this would be nice to have in phobos if it's not already there.
Re: std.widows.registry
On Wednesday, 22 August 2012 at 14:52:00 UTC, Kai Meyer wrote: If I try to modify a registry value with 'key.setValue()', I get an error 5, which I think is ERROR_ACCESS_DENIED. Even if I right click my .exe and choose 'run as Administrator'. I am on Windows 7 x64, and dmd 2.060. From my research, I think I have to modify my privilege tokens: http://msdn.microsoft.com/en-us/library/windows/desktop/aa387705%28v=vs.85%29.aspx But this example calls methods in advapi that I can't find any bindings for in the D source, namely: OpenProcessToken LookupPrivilegeValueW AdjustTokenPrivileges Any ideas? Doh, I just found it. REGSAM.KEY_ALL_ACCESS..
Link against MinGW libraries
There's got to be a way to link against libraries generated by MinGW, right? I'm using CMake to create a very simple 1 method library. If I tell D to link against the .lib (simple ar archive), it complains that it's an invalid library. If I tell D to link against the .dll, it complains that there is no .lib. I seem to remember thinking that Microsoft tools create a .dll and a .lib for development libraries, and you link against the .lib but run against the .dll. I don't know how to make MinGW (or cmake for that matter) generate both the .dll and .lib. I seem to remember that other projects I've built with the Visual Studio compiler, I get .lib and .dll files for my shared libraries, and those seem to work. Any help would be appreciated.
std.widows.registry
If I try to modify a registry value with 'key.setValue()', I get an error 5, which I think is ERROR_ACCESS_DENIED. Even if I right click my .exe and choose 'run as Administrator'. I am on Windows 7 x64, and dmd 2.060. From my research, I think I have to modify my privilege tokens: http://msdn.microsoft.com/en-us/library/windows/desktop/aa387705%28v=vs.85%29.aspx But this example calls methods in advapi that I can't find any bindings for in the D source, namely: OpenProcessToken LookupPrivilegeValueW AdjustTokenPrivileges Any ideas?
Re: Segmentation fault hell in D
On 06/08/2012 11:30 AM, "Jarl André" " wrote: Evry single time I encounter them I yawn. It means using the next frickin hour to comment away code, add more log statements and try to eleminate whats creating the hell of bugz, segmantation fault. Why can't the compiler tell me anything else than the fact that i have referenced data that does not exist? Thanks I knew that. Now, please tell me where the error occured Jeezes. If you build with -debug, it should enable code that will do those checks for you in things like arrays and associative arrays (where I find I have the most problems). It'll throw an exception rather than segfault. Very handy.
CMake for D
I have some D code that I would like to integrate into an existing CMake infrastructure. I've seen these two projects: http://www.dsource.org/projects/cmaked http://plplot.svn.sourceforge.net/viewvc/plplot/trunk/cmake/modules/language_support/cmake/Platform/ Both are quite old. Can anybody comment on the usability of either of these projects? Or perhaps point me to another project that will work?
Re: Using "in" with associative arrays and then indexing them (efficiency)
On 01/03/2012 04:07 AM, Jonathan M Davis wrote: On Tuesday, January 03, 2012 11:52:13 Matej Nanut wrote: Hello everyone, I would like to know whether if (symbol in symbols) return symbols[symbol]; is any less efficient than auto tmp = symbol in symbols; if (tmp !is null) return *tmp; Without optimisation, it looks like the first example searches for `symbol' twice. Of course it does. in does a search and returns a pointer to the element in the AA (or null if it isn't there). The subscript operator also does a search, returning the element if it's there and blowing up if it's not (OutOfRangeError IIRC without -release and who-knows-what with -release). So, if you use in and then the subscript operator, of course it's going to search twice. Part of the point of using in is to not have to do a double lookup (like you would be doing if AAs had a contains function and you called that prior to using the substript operator). The correct way to do it is the second way, though you should be able to reduce it to if(auto tmp = symbol in symbols) return *tmp; - Jonathan M Davis +1 Very slick :)
Re: newbie question: Can D do this?
On 12/19/2011 09:17 AM, clk wrote: Hello, I'm new to this mailing list. I'm trying to learn D to eventually use it in production code. I'm a little bit intimidated by the fact that the topics in the d-learn list look rather advanced to a newbie like me. I have 3 fairly simple questions: 1) Does D support something like the javascript 1.8 destructuring assigment (multiple assigment in python): [a, b] = [b, a]; I would love multiple assignment like this, but it's tricky. But your usage isn't really multiple assignment as much as it is a swap. What I'd love is something like this: [a, b, c] = [get_a(), get_b(), get_c()]; Or [a, b, c] = [to!(int)(argv[1]), some_other_value, argv[4]); 2) D doesn't seem to support the list comprehension syntax available in python and javascript. Is this correct? [f(x) for x in list if condition] No, D's syntax is very C-ish. I don't expect syntax like this to ever show up (though what you are doing is possible with things like std.algorithm) 3) D's slice operator apparently doesn't allow the use of a stride other than unity as is allowed with fortran and matlab. Is there a way to implement this feature so that [1, 2, 3, 4, 5][0..$:2] would refer to [1, 3, 5], etc..., where 2 is the non unit stride. Or is the find function from std.algorithm the only option to achieve the same behavior. Ya, std.range, like Ali said. I find the 3 features above extremely convenient in every day coding. Thanks, -clk
Re: Download file via http
On 12/13/2011 11:10 AM, Regan Heath wrote: On Tue, 13 Dec 2011 17:58:57 -, Kai Meyer wrote: On 12/13/2011 10:39 AM, Vladimir Panteleev wrote: On Tuesday, 13 December 2011 at 17:29:20 UTC, Kai Meyer wrote: I get bytes_needed from the Content-Length header. The I get the correct number of bytes from the Content-Length, bytes_needed gets the right value, but the resulting file isn't right. The file has the right number of bytes, but I appear to have an extra '0a' at the very beginning of the file, but if I do 'ss.getchar()', to get rid of it, I get an exception that there's not enough data in the stream. In an HTTP request, the headers are separated from the body by an empty line. Headers use CR/LF line endings, so the body is always preceded by a 0D 0A 0D 0A sequence. It looks like your code is not snipping the last 0A. Where did the getchar method come from? There is no mention of it in Phobos. Perhaps you could try the read(out ubyte) method? http://www.d-programming-language.org/phobos/std_stream.html Oh, I meant getc(), not getchar(), sorry. It looks like read(out ubyte) worked on windows. I'm using ss.readLine() to pull headers from the stream. When the string returned from ss.readLine() is empty, then I move on to the stream. I'm going to be using this application on Windows, Linux, and Mac, which is why I chose D. This feels like I've just entered the newline/carriage return nightmare. Should I not be using readLine()? Or is there some generic code that will always work and stick me at the beginning of the file? I would have expected what you're doing to work. IIRC when you make a GET request you send HTTP/1.0 or HTTP/1.1 or similar in the GET request line, right? (my memory of the syntax is a bit fuzzy). Warning, wacky idea with little/no backing knowledge.. IIRC using HTTP/1.1 introduced additional data into the response, lengths or checksums, or something - I never did get to the bottom of it. But, if you change to using HTTP/1.0 they go away. I wonder if the 0A is related to that. As a simple test you could try HTTP/1.0 in your request and look at the response content-length, it might just be 1 byte shorter as a result. Regan Doing a read(out ubyte) read a single byte from the stream, and allowed me to continue to read the full content-length number of bytes. Switching read(out ubyte) for a simple getc() caused the not-enough-bytes in stream exception. I'm now downloading the correct size file with bytes in the correct places after calling read(). I may or may not play with HTTP/1.0. I need to turn my attention to other matters at the moment though, since it currently "works". -Kai Meyer
Re: Download file via http
On 12/13/2011 10:39 AM, Vladimir Panteleev wrote: On Tuesday, 13 December 2011 at 17:29:20 UTC, Kai Meyer wrote: I get bytes_needed from the Content-Length header. The I get the correct number of bytes from the Content-Length, bytes_needed gets the right value, but the resulting file isn't right. The file has the right number of bytes, but I appear to have an extra '0a' at the very beginning of the file, but if I do 'ss.getchar()', to get rid of it, I get an exception that there's not enough data in the stream. In an HTTP request, the headers are separated from the body by an empty line. Headers use CR/LF line endings, so the body is always preceded by a 0D 0A 0D 0A sequence. It looks like your code is not snipping the last 0A. Where did the getchar method come from? There is no mention of it in Phobos. Perhaps you could try the read(out ubyte) method? http://www.d-programming-language.org/phobos/std_stream.html Oh, I meant getc(), not getchar(), sorry. It looks like read(out ubyte) worked on windows. I'm using ss.readLine() to pull headers from the stream. When the string returned from ss.readLine() is empty, then I move on to the stream. I'm going to be using this application on Windows, Linux, and Mac, which is why I chose D. This feels like I've just entered the newline/carriage return nightmare. Should I not be using readLine()? Or is there some generic code that will always work and stick me at the beginning of the file? -Kai Meyer
Download file via http
I've been trying to modify the htmlget.d example for std.socketstream (http://www.d-programming-language.org/phobos/std_socketstream.html) to be able to download a file. My code ends up looking like this at the end: auto outfile = new std.stream.File(destination, FileMode.Out); outfile.copyFrom(ss, bytes_needed); I get bytes_needed from the Content-Length header. The I get the correct number of bytes from the Content-Length, bytes_needed gets the right value, but the resulting file isn't right. The file has the right number of bytes, but I appear to have an extra '0a' at the very beginning of the file, but if I do 'ss.getchar()', to get rid of it, I get an exception that there's not enough data in the stream. Here's the output from hexdump that I'm basing my analysis from. Sorry if it doesn't come through 100% formatted correctly. [kai@server _source]$ hexdump -C correct_file.exe | head 4d 5a 60 00 01 00 00 00 04 00 10 00 ff ff 00 00 |MZ`.| 0010 fe 00 00 00 12 00 00 00 40 00 00 00 00 00 00 00 |@...| 0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 || 0030 00 00 00 00 00 00 00 00 00 00 00 00 60 00 00 00 |`...| 0040 52 65 71 75 69 72 65 73 20 57 69 6e 33 32 20 20 |Requires Win32 | 0050 20 24 16 1f 33 d2 b4 09 cd 21 b8 01 4c cd 21 00 | $..3!..L.!.| 0060 50 45 00 00 4c 01 06 00 00 00 00 00 00 00 00 00 |PE..L...| 0070 00 00 00 00 e0 00 8e 81 0b 01 08 00 00 7e 28 00 |.~(.| 0080 00 02 00 00 00 00 00 00 8c d7 27 00 00 20 00 00 |..'.. ..| 0090 00 a0 28 00 00 00 40 00 00 10 00 00 00 02 00 00 |..(...@.| [kai@server _source]$ hexdump -C downloaded_file.exe | head 0a 4d 5a 60 00 01 00 00 00 04 00 10 00 ff ff 00 |.MZ`| 0010 00 fe 00 00 00 12 00 00 00 40 00 00 00 00 00 00 |.@..| 0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 || 0030 00 00 00 00 00 00 00 00 00 00 00 00 00 60 00 00 |.`..| 0040 00 52 65 71 75 69 72 65 73 20 57 69 6e 33 32 20 |.Requires Win32 | 0050 20 20 24 16 1f 33 d2 b4 09 cd 21 b8 01 4c cd 21 | $..3!..L.!| 0060 00 50 45 00 00 4c 01 06 00 00 00 00 00 00 00 00 |.PE..L..| 0070 00 00 00 00 00 e0 00 8e 81 0b 01 08 00 00 7e 28 |..~(| 0080 00 00 02 00 00 00 00 00 00 8c d7 27 00 00 20 00 |...'.. .| 0090 00 00 a0 28 00 00 00 40 00 00 10 00 00 00 02 00 |...(...@| [kai@server _source]$ hexdump -C correct_file.exe | tail 002b5c10 80 30 84 30 88 30 8c 30 90 30 94 30 98 30 9c 30 |.0.0.0.0.0.0.0.0| 002b5c20 a0 30 a4 30 a8 30 ac 30 b0 30 b4 30 b8 30 bc 30 |.0.0.0.0.0.0.0.0| 002b5c30 c0 30 c4 30 c8 30 cc 30 d0 30 d4 30 d8 30 dc 30 |.0.0.0.0.0.0.0.0| 002b5c40 f4 30 f8 30 fc 30 00 31 64 31 68 31 6c 31 70 31 |.0.0.0.1d1h1l1p1| 002b5c50 74 31 38 37 00 00 00 00 00 00 00 00 00 00 00 00 |t187| 002b5c60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 || * 002b5e00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 || 002b5e10 00 00 00 00 00 00 00 00 00 00 00 00 || 002b5e1c [kai@server _source]$ hexdump -C downloaded_file.exe | tail 002b5c10 30 80 30 84 30 88 30 8c 30 90 30 94 30 98 30 9c |0.0.0.0.0.0.0.0.| 002b5c20 30 a0 30 a4 30 a8 30 ac 30 b0 30 b4 30 b8 30 bc |0.0.0.0.0.0.0.0.| 002b5c30 30 c0 30 c4 30 c8 30 cc 30 d0 30 d4 30 d8 30 dc |0.0.0.0.0.0.0.0.| 002b5c40 30 f4 30 f8 30 fc 30 00 31 64 31 68 31 6c 31 70 |0.0.0.0.1d1h1l1p| 002b5c50 31 74 31 38 37 00 00 00 00 00 00 00 00 00 00 00 |1t187...| 002b5c60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 || * 002b5e00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 || 002b5e10 00 00 00 00 00 00 00 00 00 00 00 00 ||
std.json dynamic initialization of JSONValue
I'm finding std.json extremely well written, with one glaring exception. I can't seem to figure out how to do this: JSONValue root = JSONValue(null, JSON_TYPE.OBJECT); root.object["first_object"] = JSONValue(null, JSON_TYPE.OBJECT); root.object["first_string"] = JSONValue("first_string", JSON_TYPE.STRING); which would decode to: {"first_object":{},"first_string":"first_string"} What I end up having to do is: JSONValue root; root.type = JSON_TYPE.OBJECT; root.object["first_object"] = JSONValue(); root.object["first_object"].type = JSON_TYPE.OBJECT; root.object["first_string"] = JSON_Value(); root.object["first_string"].type = JSON_TYPE.STRING; root.object["first_string"].str = "first_string"; That just feels like I'm doing it wrong. Is there a way to dynamically initialize a JSONValue struct? If I try to intialize the JSONValue object with anything other than simply null, or empty string, I either get a compile error or a segfault at run-time. root.object["first_object"] = JSONValue(null, JSON_TYPE.OBJECT); compile error: Error: overlapping initialization for integer root.object["first_string"] = JSONValue("first_string"); run-time segfault. Any ideas?
Re: About File.rawWrite
On 11/29/2011 08:00 AM, Denis Shelomovskij wrote: 29.11.2011 15:57, bearophile пишет: This D2 program runs in about 5.13 seconds on my PC: import std.stdio; void main() { auto f = File("bytes_test.dat", "wb"); ubyte[3] RGB; foreach (_; 0 .. 1_000_000) f.rawWrite(RGB); } While this C program runs in about 0.14 seconds: #include int main() { FILE *f = fopen("bytes_test.dat", "wb"); unsigned char RGB[3] = {0}; int i; for (i = 0; i< 100; i++) fwrite(RGB, 1, 3, f); return 0; } Is my D2 program wrong, or is File.rawWrite in need of some improvements? (Writing 3 bytes at a time is not efficient, but the C code shows that the runtime is acceptable for me for small files). Bye, bearophile Your OS is Windows, right? On Windows, rawWrite and rawRead always flushes stream, sets binary mode, reads/writes, flushes stream again, sets previous mode. This is definitely unnecessary slow - at least it should change mode only if needed (the file is opened in a text mode). The better solution is to change all other functions so the file mode will be changed lazily (for a text file, raw* functions will change file mode and leave file in this mode until a call of a function, that really needs a file to be in a text mode). By the way, why this changing mode behaviour is Windows only? Yes, it is clearly documented that this is the case, but it isn't documented _why_ this is the case. Quick link to the current rawRead implementation (for happy owners of Google's Chrome, the fastest beautiful web browser that can BSOD your Windows even without administrator rights) (the link isn't for Firefox: it will slow down the browser and be displayed incorrectly): https://github.com/D-Programming-Language/phobos/blob/master/std/stdio.d#L458 My firefox handled the link just fine. Ofcourse my dev machine is an 8 core i7 with 16 GB of ram. -Kai Meyer
Re: DFastCGI
On 11/22/2011 07:26 AM, bioinfornatics wrote: dear, i started to interface fastcgi to D https://github.com/bioinfornatics/DFastCGI They are a Readme and some example for quick start at this time take example from examples/test3_fcgiapp.d Any help are welcome Thanks I don't see a test3_fcgiapp.d, but I've tested the test_fcgiapp on CentOS 6 with dmd (the Fedora rpm works great). Once I fixed the build script to work properly on my machine, everything else worked out of the box. I installed fastcgi fresh on my server just to test this, no extra config required. I'm not very good with github, or I would have forked, and submitted a pull request. diff --git a/build.sh b/build.sh index 4c2e737..cf7b64a 100755 --- a/build.sh +++ b/build.sh @@ -49,7 +49,7 @@ DESTDIR="../install" LIBDIR_PATH="" DFLAGS="-w -g -op -c -od../build" -while getopts âhvqscf:l:p:â OPTION +while getopts âhvqsc:f:l:p:â OPTION do case $OPTION in c) @@ -202,11 +202,11 @@ case ${DC} in echo "not supported" else if [[ $VERBOSE -ge 2 ]]; then -echo -e "${DC} -link *.o -of ${LIBDIR_PATH}/libDFastCGI-${COMPILER}.a" +echo -e "${DC} -lib *.o -of${LIBDIR_PATH}/libDFastCGI-${COMPILER}.a" fi -${DC} -link $(find . -name "*.o") -of ${LIBDIR_PATH}/libDFastCGI-${COMPILER}.a +${DC} -lib $(find . -name "*.o") -of${LIBDIR_PATH}/libDFastCGI-${COMPILER}.a if [[ $? -ge 1 ]]; then -fail "${DC} -link" +fail "${DC} -lib" fi fi ;;
Re: Queue thread
On 11/21/2011 11:27 AM, Andrej Mitrovic wrote: How come you don't have any threads per CPU? I guess this is a difference between multi-processor and multi-core machines maybe? I don't know, I'm not much of a hardware guy. Here's the 8th CPU's entry from /proc/cpuinfo. This is a Dell Optiplex 980 processor : 7 vendor_id : GenuineIntel cpu family : 6 model : 30 model name : Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz stepping: 5 cpu MHz : 1197.000 cache size : 8192 KB physical id : 0 siblings: 8 core id : 3 cpu cores : 4 apicid : 7 initial apicid : 7 fpu : yes fpu_exception : yes cpuid level : 11 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology nonstop_tsc aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 popcnt lahf_lm ida tpr_shadow vnmi flexpriority ept vpid bogomips: 5585.03 clflush size: 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management:
Re: Queue thread
On 11/20/2011 02:36 PM, bioinfornatics wrote: Le dimanche 20 novembre 2011 à 03:09 -0800, Jonathan M Davis a écrit : On Sunday, November 20, 2011 11:59:14 bioinfornatics wrote: Dear, I would like to know if they are a way to run run a queue thread an run (nb core * 2 + 1) = nb thread in same time something like: size_t nb_core = 9; Queue q = new Queue( 9, process1, process2, process3 ); q.run(); Look at std.parallelism. I don't know if it'll do quite what you want, but it's the closest that you'll find in Phobos. - Jonathan M Davis i have tred to use TaskPool but i fail Error: /parallelism.d(434): Error: no property 'opCall' for type 'fastcgi.application.Page' the problem raise here: https://github.com/bioinfornatics/DFastCGI/blob/master/src/fastcgi/application.d#L74 (i think) Any help are welcome thanks I looked at your code, and saw this: https://github.com/bioinfornatics/DFastCGI/blob/master/src/fastcgi/application.d#L18 _taskPool = new TaskPool( totalCPUs * threadsPerCPU + 1); On my machine, that would come out to 1: [kai.meyer@kai-rhel6 D]$ cat cpu.d import std.stdio; import std.parallelism : totalCPUs, TaskPool, task; import std.cpuid : threadsPerCPU; void main() { writefln("totalCPUs %s", totalCPUs); writefln("threadsPerCPU %s", threadsPerCPU); writefln("totalCPUs * threadsPerCPU + 1 = %s\n", totalCPUs * threadsPerCPU + 1); } [kai.meyer@kai-rhel6 D]$ dmd -run cpu.d totalCPUs 8 threadsPerCPU 0 totalCPUs * threadsPerCPU + 1 = 1 Did you mean this? _taskPool = new TaskPool( totalCPUs * (threadsPerCPU + 1));
Re: Smartest way to read a number?
I don't get the exception on Linux after a new line, I have to wait until EOF, which is typically the end of the program if reading from STDIN. Not very useful. import std.stdio; T readNumber(T)() { T result; stdin.readf("%s", &result); return result; } void main() { try { int n = readNumber!int(); writeln(n); float f = readNumber!float();; writeln(f); } catch(Exception e) { writeln(e.msg); } } Sample execution: --- [kai.meyer@kai-rhel6 D]$ dmd -run readnum.d a 1 1.2 ** I hit Ctrl-D here, so this line isn't part of the output *** std.conv(1157): Can't convert value `a 1 1.2 ' of type LockingTextReader to type int --- Or if you prefer with out my terminal echoing my input: --- [kai.meyer@kai-rhel6 D]$ echo -e 'a\n1\n1.2\n' | dmd -run readnum.d std.conv(1157): Can't convert value `a 1 1.2 ' of type LockingTextReader to type int -- On 11/10/2011 02:58 PM, Tobias Brandt wrote: import std.stdio; T readNumber(T)() { T result; stdin.readf("%s",&result); return result; } Throws a ConvException if the input string wasn't in the right format. On 10 November 2011 22:48, Fabian wrote: Hey guys. I just want to write a few console applications. Usualy I have to read numbers to calculate some values. But what's the smartest way to read and convert the input? I've coded these lines: import std.stdio, std.string, std.conv; T readNumber(T)() { string buffer; stdin.readln(buffer); buffer = chomp(buffer); if(isNumeric(buffer)) { return parse!T(buffer); } else { throw new Exception("Input is not a number!"); } } void main() { try { int n = readNumber!int(); writeln(n); float f = readNumber!float(); writeln(f); } catch(Exception e) { writeln(e.msg); } } Can I use that function or is there a cleaner way to do this job? Greetings Fabian
Re: making a really simple dll.
On 08/18/2011 01:32 PM, Trass3r wrote: Am 18.08.2011, 21:17 Uhr, schrieb Adam D. Ruppe : We should make a mixin template DllMain that has a generic main. We should also have a -shared switch that transparently includes all of the boilerplate crap: particularly the .def file, maybe even a default DllMain if none exists. This would be my vote. -shared will: 1) check if there is a DllMain defined at the end, and if not, sticks a generic one in there 2) check if there are any exported functions (via .def or export()), if not, export them all That way, the OP's original simple 1 function d file compiles to a dll. Same goes for the Linux side. Default constructor and destructors that initialize and destroy the D runtime if there aren't any defined at the end of the compilation. -Kai Meyer
Re: Modify thread-local storage from parent thread
On 08/09/2011 10:27 AM, Steven Schveighoffer wrote: On Tue, 09 Aug 2011 11:36:13 -0400, Kai Meyer wrote: On 08/08/2011 01:38 PM, Steven Schveighoffer wrote: On Mon, 08 Aug 2011 14:17:28 -0400, Kai Meyer wrote: I am playing with threading, and I am doing something like this: file.rawRead(bytes); auto tmpTask = task!do_something(bytes.idup); task_pool.put(tmpTask); Is there a way to avoid the idup (or can somebody explain why idup here is not expensive?) I'd have to see where bytes is created, if it's created in the same context, just casting to immutable is allowed, as long as you never use the mutable reference again. If the logic above is expressed as: Read bytes into an array Create a thread (task) to execute a function that takes a copy of 'bytes' Execute the thread I wonder if I could: Create a thread (task) Read bytes directly into the tasks' thread local storage Execute the thread This *might* be possible. However, in many cases, the OS is responsible for creating the TLS when the thread starts, so you have to wait until the thread is actually running to access it (not an expert on this, but I think this is the case for everything but OSX?) So you would have to create the thread, have it pause while you fill it's TLS, then resume it. But I think this is clearly a weird approach to this problem. Finding a way to reliably pass the data to the sub-thread seems more appropriate. BTW, I've dealt with having to access other threads' TLS. It's not pretty, and I don't recommend using it except in specialized situations (mine was adding a GC hook). -Steve Well, bytes is in a loop, so casting to immutable wouldn't do it. The idea is to read a block of bytes, and hand them off to a worker thread to operate on those set of bytes. Everything is working, I'm just trying to avoid having to reallocate that block of bytes for the read, and then reallocate them again to pass them off to the worker thread. If I could get away with one allocation, I'd be happier. OK, there are other options. First, you could keep a "pool" of buffers, which are marked as shared. When you want to run a task, get one of those buffers, fill it, then pass the buffer to the task thread to process. Make sure the task thread puts the buffer back into the pool when it's done. I'd recommend casting the buffer to unshared while inside the task thread to save some cycles. This is probably the option I'd go with. Second, you can have the task thread give you it's TLS buffer to read data into (you need to do some casting to get this around the type system). Note that in order for it truly to be stored in TLS, the buffer has to be a fixed-sized array. -Steve These are concepts that I'm only familiar with. I think I would like to try the "pool" of buffers. I can't say I know how to mark buffers as shared, though. Could you modify this for me, to show me an example? import std.parallelism; ubyte[8][] pool; // Dynamic array of (array of 8 bytes) void thread_func() { //my_pool[0] = 50; } void main(string[] args) { uint threads = 2; pool.length = threads; TaskPool taskpool = new TaskPool(threads); foreach(i; 0..threads) { auto tmpTask = task!thread_func(); taskpool.put(tmpTask); } taskpool.stop(); }
Re: We have slices, do we have Strides?
On 08/09/2011 09:37 AM, Steven Schveighoffer wrote: On Tue, 09 Aug 2011 11:29:52 -0400, Kai Meyer wrote: On 08/08/2011 05:25 PM, Steven Schveighoffer wrote: On Mon, 08 Aug 2011 18:33:55 -0400, Kai Meyer wrote: On 08/08/2011 12:55 PM, Jonathan M Davis wrote: I have a problem I'd really like to use Strides for to simplify my code. Currently, I do this: foreach(n; 0..chunks) comp_arr[n] = values[(n * step_size) + n] if(!all_same(comp_arr, comp_arr[0])) It would eliminate an entire 2 lines of code for each time I want strides, to be able to do this: if(!all_same(bytes[i..$..step_size]) Meaning, start with i, grab all elements at i + block_size * n until block_size * n> bytes.length. Right? -Kai Meyer Would std.range.stride work for you? - Jonathan M Davis It would, if there was a way to give it an offset: int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]; fixed: assert(equal(stride(a, 3), [ 1, 4, 7, 10 ][])); assert(equal(stride(a[1..$], 3), [ 2, 5, 8, 11 ][])); assert(equal(stride(a[2..$], 3), [ 3, 6, 9 ][])); assert(equal(stride(a[3..$], 3), [ 4, 7, 10 ][])); -Steve Doh, how do I extract the array from the return value of stride? import std.range; int do_something(int[] values) { return values[0]; } void main(string[] args) { int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]; do_something(stride(a,3)); } I get: moo.d(9): Error: function moo.do_something (int[] values) is not callable using argument types (Result) moo.d(9): Error: cannot implicitly convert expression (stride(a,3LU)) of type Result to int[] Two options, first, you can change do_something to accept a range (depending on what the real implementation of do_something is, you might need to require a random-access range, but that dummy implementation could accept any input range, just return x.front): int do_something(R)(R values) if (isInputRange!R && is(ElementType!R : int)) { return values.front; // maybe need random access in real code? } Second option, convert range to an array. This incurs a memory allocation to create the array: import std.array; ... void main(...) { ... do_something(array(stride(a, 3))); } doc for std.array.array: http://www.d-programming-language.org/phobos/std_array.html#array -Steve Both of those solutions worked, thanks :)
Re: Modify thread-local storage from parent thread
On 08/08/2011 01:38 PM, Steven Schveighoffer wrote: On Mon, 08 Aug 2011 14:17:28 -0400, Kai Meyer wrote: I am playing with threading, and I am doing something like this: file.rawRead(bytes); auto tmpTask = task!do_something(bytes.idup); task_pool.put(tmpTask); Is there a way to avoid the idup (or can somebody explain why idup here is not expensive?) I'd have to see where bytes is created, if it's created in the same context, just casting to immutable is allowed, as long as you never use the mutable reference again. If the logic above is expressed as: Read bytes into an array Create a thread (task) to execute a function that takes a copy of 'bytes' Execute the thread I wonder if I could: Create a thread (task) Read bytes directly into the tasks' thread local storage Execute the thread This *might* be possible. However, in many cases, the OS is responsible for creating the TLS when the thread starts, so you have to wait until the thread is actually running to access it (not an expert on this, but I think this is the case for everything but OSX?) So you would have to create the thread, have it pause while you fill it's TLS, then resume it. But I think this is clearly a weird approach to this problem. Finding a way to reliably pass the data to the sub-thread seems more appropriate. BTW, I've dealt with having to access other threads' TLS. It's not pretty, and I don't recommend using it except in specialized situations (mine was adding a GC hook). -Steve Well, bytes is in a loop, so casting to immutable wouldn't do it. The idea is to read a block of bytes, and hand them off to a worker thread to operate on those set of bytes. Everything is working, I'm just trying to avoid having to reallocate that block of bytes for the read, and then reallocate them again to pass them off to the worker thread. If I could get away with one allocation, I'd be happier. -Kai Meyer
Re: We have slices, do we have Strides?
On 08/08/2011 05:25 PM, Steven Schveighoffer wrote: On Mon, 08 Aug 2011 18:33:55 -0400, Kai Meyer wrote: On 08/08/2011 12:55 PM, Jonathan M Davis wrote: I have a problem I'd really like to use Strides for to simplify my code. Currently, I do this: foreach(n; 0..chunks) comp_arr[n] = values[(n * step_size) + n] if(!all_same(comp_arr, comp_arr[0])) It would eliminate an entire 2 lines of code for each time I want strides, to be able to do this: if(!all_same(bytes[i..$..step_size]) Meaning, start with i, grab all elements at i + block_size * n until block_size * n> bytes.length. Right? -Kai Meyer Would std.range.stride work for you? - Jonathan M Davis It would, if there was a way to give it an offset: int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]; fixed: assert(equal(stride(a, 3), [ 1, 4, 7, 10 ][])); assert(equal(stride(a[1..$], 3), [ 2, 5, 8, 11 ][])); assert(equal(stride(a[2..$], 3), [ 3, 6, 9 ][])); assert(equal(stride(a[3..$], 3), [ 4, 7, 10 ][])); -Steve Doh, how do I extract the array from the return value of stride? import std.range; int do_something(int[] values) { return values[0]; } void main(string[] args) { int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]; do_something(stride(a,3)); } I get: moo.d(9): Error: function moo.do_something (int[] values) is not callable using argument types (Result) moo.d(9): Error: cannot implicitly convert expression (stride(a,3LU)) of type Result to int[]
Re: We have slices, do we have Strides?
On 08/08/2011 05:25 PM, Steven Schveighoffer wrote: On Mon, 08 Aug 2011 18:33:55 -0400, Kai Meyer wrote: On 08/08/2011 12:55 PM, Jonathan M Davis wrote: I have a problem I'd really like to use Strides for to simplify my code. Currently, I do this: foreach(n; 0..chunks) comp_arr[n] = values[(n * step_size) + n] if(!all_same(comp_arr, comp_arr[0])) It would eliminate an entire 2 lines of code for each time I want strides, to be able to do this: if(!all_same(bytes[i..$..step_size]) Meaning, start with i, grab all elements at i + block_size * n until block_size * n> bytes.length. Right? -Kai Meyer Would std.range.stride work for you? - Jonathan M Davis It would, if there was a way to give it an offset: int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]; fixed: assert(equal(stride(a, 3), [ 1, 4, 7, 10 ][])); assert(equal(stride(a[1..$], 3), [ 2, 5, 8, 11 ][])); assert(equal(stride(a[2..$], 3), [ 3, 6, 9 ][])); assert(equal(stride(a[3..$], 3), [ 4, 7, 10 ][])); -Steve Awesome :) Thanks Steve!
Re: We have slices, do we have Strides?
On 08/08/2011 12:55 PM, Jonathan M Davis wrote: I have a problem I'd really like to use Strides for to simplify my code. Currently, I do this: foreach(n; 0..chunks) comp_arr[n] = values[(n * step_size) + n] if(!all_same(comp_arr, comp_arr[0])) It would eliminate an entire 2 lines of code for each time I want strides, to be able to do this: if(!all_same(bytes[i..$..step_size]) Meaning, start with i, grab all elements at i + block_size * n until block_size * n> bytes.length. Right? -Kai Meyer Would std.range.stride work for you? - Jonathan M Davis It would, if there was a way to give it an offset: int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]; assert(equal(stride(a, 3), [ 1, 4, 7, 10 ][])); assert(equal(stride(a, 3, 1), [ 2, 5, 8, 11 ][])); assert(equal(stride(a, 3, 2), [ 3, 6, 9 ][])); assert(equal(stride(a, 3, 3), [ 4, 7, 10 ][])); Is that possible?
Modify thread-local storage from parent thread
I am playing with threading, and I am doing something like this: file.rawRead(bytes); auto tmpTask = task!do_something(bytes.idup); task_pool.put(tmpTask); Is there a way to avoid the idup (or can somebody explain why idup here is not expensive?) If the logic above is expressed as: Read bytes into an array Create a thread (task) to execute a function that takes a copy of 'bytes' Execute the thread I wonder if I could: Create a thread (task) Read bytes directly into the tasks' thread local storage Execute the thread
We have slices, do we have Strides?
I have a problem I'd really like to use Strides for to simplify my code. Currently, I do this: foreach(n; 0..chunks) comp_arr[n] = values[(n * step_size) + n] if(!all_same(comp_arr, comp_arr[0])) It would eliminate an entire 2 lines of code for each time I want strides, to be able to do this: if(!all_same(bytes[i..$..step_size]) Meaning, start with i, grab all elements at i + block_size * n until block_size * n > bytes.length. Right? -Kai Meyer
Re: Multi-file byte comparison tool. What would you have done differently?
On 08/08/2011 12:33 AM, Pelle wrote: On Fri, 05 Aug 2011 18:43:27 +0200, Kai Meyer wrote: On 08/05/2011 03:02 AM, Pelle wrote: Don't declare variables until you need them, just leave bytes_read and bytes_max here. Is there a performance consideration? Or is it purely a style or D-Factor suggestion? Just style and D-factor :-) Also, resulting code is shorter, and you can replace a lot of type names with auto. I don't understand why you use ByteUnion instead of just a plain array of bytes. I thought that comparing one byte at a time would be slower than comparing 8 bytes at a time (size_t on 64bit) and failing over to the byte-by-byte comparison only when the size_t value was different. Maybe, but that's something that should be benchmarked. If a byte array is just as fast, and the code is simpler, that's a better solution :) I simply can't imagine how 8,000 byte comparisons would be even close to comparable to 1,000 size_t comparisons done one at a time, with the way I'm doing the comparison. I'm certain there are much better ways of comparing bits, but I'm not ready to make this program that complex :)
Re: Multi-file byte comparison tool. What would you have done differently?
On 08/05/2011 11:13 AM, Jonathan M Davis wrote: On 08/05/2011 03:02 AM, Pelle wrote: On Fri, 05 Aug 2011 00:25:38 +0200, Kai Meyer wrote: I have a need for detecting incorrect byte sequences in multiple files (>2) at a time (as a part of our porting effort to new platforms.) Ideally the files should be identical for all but a handful of byte sequences (in a header section) that I can just skip over. I thought this would be a fun exercise for my D muscles. I found success creating a dynamic array of structs to keep information about each file passed in via command-line parameters. I'll append the code at the end (and I'm sure it'll get mangled in the process...) (I'm not one for coming up with creative names, so it's SOMETHING) Then I loop around a read for each file, then manually run a for loop from 0 to BLOCK_SIZE, copy the size_t value into a new dynamic array (one for each of the files opened), and run a function to ensure all values in the size_t array are the same. If not, I compare each ubyte value (via the byte_union) to determine which bytes are not correct by adding each byte to a separate array, and comparing each value in that array, printing the address and values of each bad byte as I encounter them. This appears to work great. Some justifications: I used size_t because I'm under the impression it's a platform specific size that best fits into a single register, thus making comparisons faster than byte-by-byte. I used a union to extract the bytes from the size_t I wanted to create a SOMETHING for each file at run-time, instead of only allowing a certain number of SOMETHINGS (either hard coded, or a limit). Originally I wrote my own comparison function, but in my search for something more functional, I tried out std.algorithm's count. Can't say I can tell if it's better or worse. Features I'll probably add if I have to keep using the tool: 1) Better support for starting points and bytes to read. 2) Threshold for errors encountered, perferrably managed by a command-line argument. 3) Coalescing error messages in sequential byte sequences. When I run the program, it's certainly I/O bound at 30Mb/s to an external USB drive :). So the question is, how would you make it more D-ish? (Do we have a term analogous to "pythonic" for D? :)) Code: import std.stdio; import std.file; import std.conv; import std.getopt; import std.algorithm; enum BLOCK_SIZE = 1024; union byte_union { size_t val; ubyte[val.sizeof] bytes; } struct SOMETHING { string file_name; size_t size_bytes; File fd; byte_union[BLOCK_SIZE] bytes; } I would use TypeNames and nonTypeNames, so, blockSize, ByteUnion, Something, sizeBytes, etc. I haven't used TypeNames or nonTypeNames. Do have some reference material for me? Searching http://www.d-programming-language.org/ didn't give me anything that sounds like what you're talking about. I believe that he was talking about how you named your variables and type names. Normall in D, user-defined types use pascal case (e.g. Something and ByteUnion, not SOMETHING and byte_union), and everything else uses camelcase (e.g. blockSize and fileName, not BLOCK_SIZE and file_name). It's an issue of style. You can name your variables however you'd like to, but what you're doing doesn't match what most of the people around here do, which can make it harder to read the code that you post. He was simply suggesting that you follow the more typical D naming conventions. It's completely up to you though. - Jonathan M Davis Thanks :) That's what I was asking for. I've got some programming habits that need to be broken if I want to increase my D-Factor!
Re: Multi-file byte comparison tool. What would you have done differently?
On 08/05/2011 03:02 AM, Pelle wrote: On Fri, 05 Aug 2011 00:25:38 +0200, Kai Meyer wrote: I have a need for detecting incorrect byte sequences in multiple files (>2) at a time (as a part of our porting effort to new platforms.) Ideally the files should be identical for all but a handful of byte sequences (in a header section) that I can just skip over. I thought this would be a fun exercise for my D muscles. I found success creating a dynamic array of structs to keep information about each file passed in via command-line parameters. I'll append the code at the end (and I'm sure it'll get mangled in the process...) (I'm not one for coming up with creative names, so it's SOMETHING) Then I loop around a read for each file, then manually run a for loop from 0 to BLOCK_SIZE, copy the size_t value into a new dynamic array (one for each of the files opened), and run a function to ensure all values in the size_t array are the same. If not, I compare each ubyte value (via the byte_union) to determine which bytes are not correct by adding each byte to a separate array, and comparing each value in that array, printing the address and values of each bad byte as I encounter them. This appears to work great. Some justifications: I used size_t because I'm under the impression it's a platform specific size that best fits into a single register, thus making comparisons faster than byte-by-byte. I used a union to extract the bytes from the size_t I wanted to create a SOMETHING for each file at run-time, instead of only allowing a certain number of SOMETHINGS (either hard coded, or a limit). Originally I wrote my own comparison function, but in my search for something more functional, I tried out std.algorithm's count. Can't say I can tell if it's better or worse. Features I'll probably add if I have to keep using the tool: 1) Better support for starting points and bytes to read. 2) Threshold for errors encountered, perferrably managed by a command-line argument. 3) Coalescing error messages in sequential byte sequences. When I run the program, it's certainly I/O bound at 30Mb/s to an external USB drive :). So the question is, how would you make it more D-ish? (Do we have a term analogous to "pythonic" for D? :)) Code: import std.stdio; import std.file; import std.conv; import std.getopt; import std.algorithm; enum BLOCK_SIZE = 1024; union byte_union { size_t val; ubyte[val.sizeof] bytes; } struct SOMETHING { string file_name; size_t size_bytes; File fd; byte_union[BLOCK_SIZE] bytes; } I would use TypeNames and nonTypeNames, so, blockSize, ByteUnion, Something, sizeBytes, etc. I haven't used TypeNames or nonTypeNames. Do have some reference material for me? Searching http://www.d-programming-language.org/ didn't give me anything that sounds like what you're talking about. void main(string[] args) { size_t bytes_read; size_t bytes_max; size_t size_smallest; size_t[] comp_arr; SOMETHING[] somethings; Don't declare variables until you need them, just leave bytes_read and bytes_max here. Is there a performance consideration? Or is it purely a style or D-Factor suggestion? getopt(args, "seek", &bytes_read, "bytes", &bytes_max ); if(bytes_max == 0) bytes_max = size_t.max; // Limit on the smallest file size else bytes_max += bytes_read; //bytes_read = bytes_read - (bytes_read % (BLOCK_SIZE * SOMETHING.size_bytes.sizeof)); size_smallest = bytes_max; somethings.length = args.length - 1; comp_arr.length = args.length - 1; for(size_t i = 0; i < somethings.length; i++) { somethings[i].file_name = args[i + 1]; somethings[i].size_bytes = getSize(somethings[i].file_name); stderr.writef("Opening file: %s(%d)\n", somethings[i].file_name, somethings[i].size_bytes); somethings[i].fd = File(somethings[i].file_name, "r"); somethings[i].fd.seek(bytes_read); if(somethings[i].fd.tell() != bytes_read) { stderr.writef("Failed to seek to position %d in %s\n", bytes_read, args[i + 1]); } // Pick the smallest file, or the limit size_smallest = min(size_smallest, somethings[i].size_bytes); } Use foreach (ref something; somethings) and something instead of somethings[i]. I didn't know ref could be used like that :) Thanks! // Check file sizes for(size_t i = 0; i < somethings.length; i++) comp_arr[i] = somethings[i].size_bytes; writef("count: %s\n", count(comp_arr, comp_arr[0])); if(count(comp_arr, comp_arr[0]) != comp_arr.length) { stderr.writef("Files are not the same size!"); foreach(s; somethings) stderr.writef("[%s:%d]", s.file_name, s.size_bytes); stderr.writef("\n"); } You can use writefln() istead of writef("\n") everywhere. It's hard to fix my printf habits :) // While bytes_read < size of smallest file size_t block_counter; while(bytes_read < size_smallest) { // Read b
Re: Multi-file byte comparison tool. What would you have done differently?
On 08/04/2011 05:03 PM, Timon Gehr wrote: Kai Meyer wrote: So the question is, how would you make it more D-ish? (Do we have a term analogous to "pythonic" for D? :)) An easy first step to improve the D-Factor would be to replace all these for loops with foreach loops and ref foreach loops. -Timon I like D-Factor :) I haven't done foreach(ref s; somethings) before. Interesting, thanks :)
Re: Minimum value in a range
On 08/04/2011 07:54 PM, bearophile wrote: Kai Meyer: Looking at std.algorithm, I think what you really want is minCount: http://www.d-programming-language.org/phobos/std_algorithm.html#minCount It's a bad design. Bye, bearophile minCount is, or the usage of minCount in his particular problem?
Multi-file byte comparison tool. What would you have done differently?
I have a need for detecting incorrect byte sequences in multiple files (>2) at a time (as a part of our porting effort to new platforms.) Ideally the files should be identical for all but a handful of byte sequences (in a header section) that I can just skip over. I thought this would be a fun exercise for my D muscles. I found success creating a dynamic array of structs to keep information about each file passed in via command-line parameters. I'll append the code at the end (and I'm sure it'll get mangled in the process...) (I'm not one for coming up with creative names, so it's SOMETHING) Then I loop around a read for each file, then manually run a for loop from 0 to BLOCK_SIZE, copy the size_t value into a new dynamic array (one for each of the files opened), and run a function to ensure all values in the size_t array are the same. If not, I compare each ubyte value (via the byte_union) to determine which bytes are not correct by adding each byte to a separate array, and comparing each value in that array, printing the address and values of each bad byte as I encounter them. This appears to work great. Some justifications: I used size_t because I'm under the impression it's a platform specific size that best fits into a single register, thus making comparisons faster than byte-by-byte. I used a union to extract the bytes from the size_t I wanted to create a SOMETHING for each file at run-time, instead of only allowing a certain number of SOMETHINGS (either hard coded, or a limit). Originally I wrote my own comparison function, but in my search for something more functional, I tried out std.algorithm's count. Can't say I can tell if it's better or worse. Features I'll probably add if I have to keep using the tool: 1) Better support for starting points and bytes to read. 2) Threshold for errors encountered, perferrably managed by a command-line argument. 3) Coalescing error messages in sequential byte sequences. When I run the program, it's certainly I/O bound at 30Mb/s to an external USB drive :). So the question is, how would you make it more D-ish? (Do we have a term analogous to "pythonic" for D? :)) Code: import std.stdio; import std.file; import std.conv; import std.getopt; import std.algorithm; enum BLOCK_SIZE = 1024; union byte_union { size_t val; ubyte[val.sizeof] bytes; } struct SOMETHING { string file_name; size_t size_bytes; File fd; byte_union[BLOCK_SIZE] bytes; } void main(string[] args) { size_t bytes_read; size_t bytes_max; size_t size_smallest; size_t[] comp_arr; SOMETHING[] somethings; getopt(args, "seek", &bytes_read, "bytes", &bytes_max ); if(bytes_max == 0) bytes_max = size_t.max; // Limit on the smallest file size else bytes_max += bytes_read; //bytes_read = bytes_read - (bytes_read % (BLOCK_SIZE * SOMETHING.size_bytes.sizeof)); size_smallest = bytes_max; somethings.length = args.length - 1; comp_arr.length = args.length - 1; for(size_t i = 0; i < somethings.length; i++) { somethings[i].file_name = args[i + 1]; somethings[i].size_bytes = getSize(somethings[i].file_name); stderr.writef("Opening file: %s(%d)\n", somethings[i].file_name, somethings[i].size_bytes); somethings[i].fd = File(somethings[i].file_name, "r"); somethings[i].fd.seek(bytes_read); if(somethings[i].fd.tell() != bytes_read) { stderr.writef("Failed to seek to position %d in %s\n", bytes_read, args[i + 1]); } // Pick the smallest file, or the limit size_smallest = min(size_smallest, somethings[i].size_bytes); } // Check file sizes for(size_t i = 0; i < somethings.length; i++) comp_arr[i] = somethings[i].size_bytes; writef("count: %s\n", count(comp_arr, comp_arr[0])); if(count(comp_arr, comp_arr[0]) != comp_arr.length) { stderr.writef("Files are not the same size!"); foreach(s; somethings) stderr.writef("[%s:%d]", s.file_name, s.size_bytes); stderr.writef("\n"); } // While bytes_read < size of smallest file size_t block_counter; while(bytes_read < size_smallest) { // Read bytes //stderr.writef("tell: "); for(size_t i = 0; i < somethings.length; i++) { //stderr.writef("Reading file %s\n", file_names[i]); //stderr.writef("%d ", somethings[i].fd.tell()); //if(somethings[0].fd.tell() + BLOCK_SIZE * SOMETHING.size_bytes.sizeof > somethings[0].size_bytes) //{ //stderr.writef("Warning, reading last block : [%d:%d:%d]\n", somethings[0].fd.tell(), somethings[0].size_bytes, somethings[0].fd.tell() + BLOCK_SIZE * SOMETHING.size_bytes.sizeof); //for(size_t j = 0; j < somethings[i].bytes.length; j++) //{ //somethings[i].bytes[i].val = 0;
Re: Minimum value in a range
On 08/02/2011 06:03 AM, Andrej Mitrovic wrote: import std.algorithm; void main() { auto x = min([1, 2, 3]); // x would be 1 } min() isn't equipped to do this on a single range. What can I use instead? I haven't had my coffee yet. :) Looking at std.algorithm, I think what you really want is minCount: http://www.d-programming-language.org/phobos/std_algorithm.html#minCount
Re: Hexadecimal string to integer
On 08/03/2011 10:44 AM, Stijn Herreman wrote: On 3/08/2011 2:32, Johann MacDonagh wrote: On 8/2/2011 8:17 PM, Stijn Herreman wrote: std.conv does not support conversion from a hexadecimal string to an integer. Is there a technical reason for this limitation? This is the best I could do, can it be improved still? int i = to!int(parse!float("0x1ap0")); parse!int("1a", 16); I tried multiple combinations but not that one, thanks. I am doing: to!(int)(BigInt("0x1a").toInt()); toInt actually returns a long: http://www.d-programming-language.org/phobos/std_bigint.html It's kinda frustrating, but it's there.
Re: Frontend and backend communication
On 07/28/2011 01:18 AM, Dainius (GreatEmerald) wrote: Hmm, there are still a whole lot of functions that call Shuffle(), so it might not be ideal. However, this gives me an idea - if a pointer to a function can be a parameter, can it be a global variable? In that case, the frontend would indeed be able to overwrite the function that the backend calls by simply altering that pointer. Yes, you could create a "function table" and keep a list of all the functions that need to be called. You can then alter the behavior of one method at runtime with out having to pass a function as a parameter. Of course, global variables are tricky things, especially whe you're threaded. It's probably simplest to just pass the function pointer as a parameter to Shuffle(). If Shuffle() indeed has multiple entry points, and they all fight to have their version of PlaySound() run at the end of Shuffle(), then you may run into problems. -Kai Meyer
Re: Frontend and backend communication
On 07/27/2011 04:40 PM, Dainius (GreatEmerald) wrote: No no. It's the other way round. Shuffle() is in the library (backend). PlaySound() is in the executable (frontend). Since I don't want the library to be dependent on any sound libraries, I can't have PlaySound() in it. And there is no other way that I can think of to execute PlaySound() just at the end of Shuffle() without capturing events (since Shuffle() itself is called by a whole lot of different functions across the library, and not from the executable itself). One reason for the confusing responses is that in your original post you said: "a frontend (a library)", "a backend (an executable)", "Shuffle() is a backend function", and "PlaySound() is a frontend one". Frontend->library->Shuffle() Backend->executable->PlaySound() Then in this email, you say: "Shuffle() is in the library (backend)", and "PlaySound() is in the executable (frontend)" Backend->library->Shuffle() Frontend->executable->PlaySound() I'm assuming that this is the more correct version. Depending on what PlaySound needs, you can pass the function as a parameter to Shuffle().
hex string to int?
Is there a built-int ton convert a hex string like "0x0A" to the int "10"?
Re: Encoding help
On 07/11/2011 10:56 AM, Kai Meyer wrote: I have a need to be able to read/write a win32 UNICODE file from a linux machine. I've heard D has some great encoding libraries. I'm struggling to get some simple reads done. How can I read a line from a UTF-16LE file on a linux box in D? I'm running dmd 2.053 -Kai Meyer Ok, fine. So I can't put readline in a foreach loop. Got it... -Kai Meyer
Encoding help
I have a need to be able to read/write a win32 UNICODE file from a linux machine. I've heard D has some great encoding libraries. I'm struggling to get some simple reads done. How can I read a line from a UTF-16LE file on a linux box in D? I'm running dmd 2.053 -Kai Meyer
Re: Any way to get the name of a function?
On 07/06/2011 08:47 PM, Andrej Mitrovic wrote: void foo(){}; void bar(){}; void main() { auto funcs = [&foo,&bar]; } I'm using this in a foreach loop and invoking each function with some predefined arguments. But I'd also like to extract the name of each function because each function does some image processing and then I save that image to disk. Basically I want to do: foreach (func; funcs) { func(arguments..); writeToFile(func.stringof); } Obviously I can't use arrays since they don't hold any name information, they just store the pointers. Can I use tuples somehow? The functions are predefined, I just need to iterate through all of them and call them and extract their name. I assume the function signatures are all the same? Then you can do an associative array: import std.stdio; int func1(int a) {return a + 1;} int func2(int a) {return a + 2;} int func3(int a) {return a + 3;} void main() { int function (int)[string] funcs = ["func1":&func1, \ "func2":&func2, "func3":&func3]; foreach(name, func; funcs) writef("%s %d\n", name, func(1)); } Perhaps a mixin would be helpful to limit cut-and-paste issues. If they are methods that are part of a class, you would need to declare them as "int delegate (int)[string] funcs".
Re: readf with strings
On 06/23/2011 02:27 AM, Dainius (GreatEmerald) wrote: I have a related enhancement request since lot of time: http://d.puremagic.com/issues/show_bug.cgi?id=4716 Bye, bearophile That's exactly what I'd like to see. Voted. After all, D is created with practicality in mind, and doing all that parsing is the opposite of what it's trying to achieve. The goal here is to have semantics for "Read an int from STDIN." I think the difficulty here is this really *should* be "Read a T from a stream." In C++, we have the stream operators ">>" and "<<". I really really really really miss these. I would love to have my stream operators back (and then implement the operators for classes and structs.) I think that "a = stdin.type_read!int();" or "std.type_read!int(&a);" would go a long way in getting there, as long as we could extend the template. I don't like the way python takes input from STDIN with raw_input() and input(). I'm not opposed to having a language support those semantics, but I would rather have a generic stream reader that does the conversion to a type for me that allows me to extend the conversion to include my own types.
Re: readf with strings
On 06/22/2011 09:30 AM, Ali Çehreli wrote: On Wed, 22 Jun 2011 14:57:57 +, GreatEmerald wrote: This should be a very elementary question. How do you get a string off stdin? Or an integer, or a boolean, for that matter? If I use this: float MyFloat; string MyString; readf("%f",&MyFloat); writeln(MyFloat); readf("%s",&MyString); writeln(MyString); I get the float printed correctly, but when it asks to input the string, whatever I input gets ignored - I can't reach the writeln part in any way and I have to forcibly close the program. The same thing is with ints - if I enter an int, it acts as if I didn't enter anything at all. But floats work fine for some reason. Any thoughts about what is happening there? I'm using openSUSE 11.4 and DMD 2.053. Reading from an input stream is sometimes confusing. Things to remember: - Use %s for any type unless there is reason not to - The line terminator from the previous entry is still in the input. (You may call readf(" ") to flush those white space characters. (I've just discovered this.)) - string can hold any character including space and the line terminator. That's why pressing the Enter doesn't terminate reading a string. - Use a space character before any format specifier to ignore zero or more whitespace characters before the previous input: " %s". - To read a string (actually a line), use chomp(readln()) - I don't know whether this is intended and I don't think that we should routinely use this: The EOF (Ctrl-D on Unix consoles, Ctrl-Z on Windows) terminates reading the string but strangely not the entire input. import std.stdio; import std.string; void main() { float MyFloat; readf(" %s",&MyFloat); writeln(MyFloat); readf(" "); string MyString = chomp(readln()); writeln(MyString); } Ali Remember that readf is reading characters, and converting them to types for you. I've just gotten in the habbit of reading in the string, and then parsing the string on my own. Readf doesn't grant me anything special that I can't do on my own. It's easy enough to do something like this: [kai.meyer@kai-rhel6 sandbox]$ cat d_read.d import std.stdio; import std.string; import std.conv; void main() { string[] buffer; int a; float b; string c; buffer = chomp(readln()).split(" "); a = to!(int)(buffer[0]); b = to!(float)(buffer[1]); c = buffer[2..$].join(" "); writef("Read in: '%d' '%f' '%s'\n", a, b, c); } If I type: 1 1.3 this is a string On the command line after the execution, I get this back: Read in: '1' '1.30' 'this is a string' It's not very stream-ish, because readln breaks on a new line. You could call the "buffer = chomp..." line again if (buffer.length == 0) before you attempt another conversion.
Re: An effort at creating a free ebook for learning D
On 06/20/2011 03:46 PM, Jose Armando Garcia wrote: On Mon, Jun 20, 2011 at 6:30 PM, Jimmy Cao wrote: I helped with something last summer: an attempt at creating a wikibook for D. At that time, my D skills were very bad, so I had to concentrate on learning D first before contributing to more lessons. One thing that has always bothered me is, there aren't many good *free* ebooks for learning D. Well, I'll try to continue what I had started less than a year ago. I'll probably make many mistakes while writing, so can you guys check on my progress once in a while? http://en.wikibooks.org/wiki/D_(The_Programming_Language)/d2/Lesson_1/Phobos What do you think? Thanks. Good idea. Small notes: *) In the tip section 'write("Hello\n") and writeln("Hello")' are not the same. writeln and writefln flush. write doesn't. *) Not sure if you want to also encourage portable code. "\n" should be replace with newline which I think it is define in std.string. I wrote some code a while back that was intended to be portable (between windows and linux anyway). I used 'writef("Hello\n");' a lot, and those always printed correctly on windows. Does writef do something different than write with the '\n' character? -Kai Meyer
Re: Is it reasonable to learn D
On 06/07/2011 01:47 PM, Fabian wrote: Dear D Community, is it reasonable to learn D? I've found a lot of good points for D but I've found a lot of negative points too. I believe that I needn't to list all the point for D but I want to give a few examples against learning D I've read in some German and English boards: - The D compiler has only bad code optimization - There are no maintained GUI libraries - The development of the compiler is very slow - Only a small community => no real German community So I ask you - Is it reasonable to learn D? I'm looking forward to your answers. Greetings Fabian PS: If you want to contact me you are allowed to write an Email to me. contact-...@freemail.de I think your question is highly subjective. D is still a young language, which I think accounts for all of the negative feedback you've listed.
Re: dmd 32bit
On 06/07/2011 01:39 PM, Kai Meyer wrote: How do I generate 32bit binaries with dmd64 (2.053) on Linux? I can't find the flag for it. -Kai Meyer Nevermind, found it. http://digitalmars.com/d/2.0/dmd-linux.html I kept putting a space between -m and 32 :(
dmd 32bit
How do I generate 32bit binaries with dmd64 (2.053) on Linux? I can't find the flag for it. -Kai Meyer
Re: correct way to create boiler plate code
On 05/16/2011 01:08 PM, dmerrio wrote: I am parsing some formulas from a spreadsheet file. To duplicate the behavior of the spreadsheet functions, I am having to create a lot of boiler plate code that maps from the spreadsheet functions to the built-in functions. Mixin would seem to allow me to automate the boiler-plate creation, but i am not utilizing it correctly. What is the correct to call Mixin in this situation, or is their a better way to create the boiler-plate code? For background, i am new to D. D is my second language with my primary experience being a script kiddie in Excel VBA, so take it slow, please. import main; //class definition of rng import std.math; //trig functions import std.conv; //to!double import std.string; //toupper double transFunc(alias transedentalFunc)(rng aRng){ try{return(transedentalFunc(aRng.getCellValue().coerce! (double)));} //cellValue stored as a Variant catch{return(transedentalFunc(to!double(aRng.getCellValue ().coerce!(string;} //replicate spreadsheet behavior and convert to a number } //Example 1 of boilerplate code double SIN(double aReal){return(sin(aReal));} double SIN(string aStr){return(sin(to!double(aStr)));} double SIN(rng aRng){return(transFunc!(sin)(aRng));} //Example 2 of boilerplate code double COS(double aReal){return(cos(aReal));} double COS(string aStr){return(cos(to!double(aStr)));} double COS(rng aRng){return(transFunc!(cos)(aRng));} string[] funcs = ["tan"]; void createFuncs(){ foreach(func; funcs){ mixin("double " ~ toupper(func) ~ "(double aReal) {return(" ~ func ~ "(aReal));}"); } } calling mixin a compile time has the following error... Error 1 Error: variable func cannot be read at compile time C:\D\SVNProjects\trunk\xcellD\xcell1\trig.d 22 thanks for your help This works: //import main; //class definition of rng import std.math; //trig functions import std.conv; //to!double import std.string; //toupper import std.stdio; void main() { mixin(createFunc!("sin")); mixin(createFunc!("cos")); mixin(createFunc!("tan")); writeln(SIN(0)); // 0 writeln(COS(0)); // 1 writeln(TAN(0)); // 0 return; } template createFunc(string func){ const char[] createFunc = "double " ~ toupper(func) ~ "(double aReal) {return(" ~ func ~ "(aReal));}"; } Stole it from http://www.digitalmars.com/d/2.0/mixin.html I don't think there's a way to use an array of strings, since (as pointed out by others and your error message) that mixins are done compile-time and foreach are done (mostly) at run-time.
Re: How to get the dang thing to work (Was: Linux: How to statically link against system libs?)
On 04/27/2011 11:51 AM, Nick Sabalausky wrote: "Kai Meyer" wrote in message news:ip9bro$1lak$1...@digitalmars.com... On 04/26/2011 02:28 PM, Nick Sabalausky wrote: Ok, so I guess statically linking against the stuff isn't the way to go, and apparently DLL hell is worse on linux. Sooo...What do I do? In the other thread, Spacen said: "The way to do this is to link against the oldest libc you need to support, thus making the binaries forward compatible" I know my way around Linux as a user, but with deeper system stuff like that I'm pretty much lost. I don't have a clue how to do what Spacen suggests or how to determine what version of libc I need. Can anyone help me out with that? Can you backup, and help me understand what the first problem was? The one you thought was solvable by statically linking against glibc? It was the thread "D CGI test: linux.so.2: bad ELF interpreter: No such file or directory". Reposted here: - I've made a little test CGI app: import std.conv; import std.stdio; void main() { auto content = "Hello world"; auto headers = `HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Content-Length: `~to!string(content.length); while(readln().length> 1) {} writeln(headers); writeln(); writeln(content); } Works on Windows command line and through IIS. And it works on my Kubuntu 10.6 (CORRECTION: It's v10.04) command line. But if I copy the executable from my Kubuntu box to my web host's Debian server (CORRECTION: It's Red Hat, but there is another server I'd like to also run on that is Debian): Running it through Apache gives me a 500, and running it directly with ssh gives me: linux.so.2: bad ELF interpreter: No such file or directory I assume that error message is the cause of the 500 (can't tell for sure because the 500 isn't even showing up in my Apache error logs). But I'm not enough of a linux expert to have the slightest clue what that error message is all about. I don't need to actually compile it *on* the server do I? I would have thought that all (or at least most) Linux distros used the same executable format - especially (K)Ubuntu and Debian. Ya, glibc tries very hard to be forward compatible, but it is quite often not very backwards compatible. Meaning, if you build on an older system, it should run on newer systems (forward compatible.) But if you build on newer systems, it's not always going to run on older systems (backwards compatible.) The best solution is to either use LSB (which is a big hoary mess to get into, and isn't fully supported everywhere, and I don't think there's anything you can do to D to make it LSB compatible), build on the oldest distro, or build on each distro. Ideally, for performance, you should build a binary for each distro. You should build one for Ubuntu separately from Debian, but if you don't ahve the time, building on Debian will likely run on Ubuntu, but not visa versa. Statically linking or dynamic linking isn't the answer, it's forward and backwards compatibility. Personally, I build rpms for both RHEL/CentOS and Fedora on a semi-regular basis, and I usually build one to distribute on RHEL/CentOS separate from a build to distribute on Fedora.
Re: How to get the dang thing to work (Was: Linux: How to statically link against system libs?)
On 04/26/2011 02:28 PM, Nick Sabalausky wrote: Ok, so I guess statically linking against the stuff isn't the way to go, and apparently DLL hell is worse on linux. Sooo...What do I do? In the other thread, Spacen said: "The way to do this is to link against the oldest libc you need to support, thus making the binaries forward compatible" I know my way around Linux as a user, but with deeper system stuff like that I'm pretty much lost. I don't have a clue how to do what Spacen suggests or how to determine what version of libc I need. Can anyone help me out with that? Can you backup, and help me understand what the first problem was? The one you thought was solvable by statically linking against glibc? -Kai Meyer
Re: std.regex with multiple matches
On 04/21/2011 11:43 AM, David Gileadi wrote: I was using std.regex yesterday, matching a regular expression against a string with the "g" flag to find multiple matches. As the example from the docs shows (BTW I think the example may be wrong; I think it needs the "g" flag added to the regex call), you can do a foreach loop on the matches like: foreach(m; match("abcabcabab", regex("ab"))) { writefln("%s[%s]%s", m.pre, m.hit, m.post); } Each match "m" is a RegexMatch, which includes .pre, .hit, and .post properties to return ranges of everything before, inside, and after the match. However what I really wanted was a way to get the range between matches, i.e. since I had multiple matches I wanted something like m.upToNextMatch. Since I'm not very familiar with ranges, am I missing some obvious way of doing this with the existing .pre, .hit and .post properties? -Dave There's two ways I can think of off the top of my head. I don't think D supports "look ahead", but if it did you could match something, then capture the portion afterwards (in m.captures[1]) that matches everything up until the look ahead (which is what you matched in the first place). Otherwise, you could manually capture the ranges like this (captures the first word character after each word boundry, then prints the remaining portion of the word until the next word boundary followed by a word character): import std.stdio; import std.regex; void main() { size_t last_pos; size_t last_size; string abc = "the quick brown fox jumped over the lazy dog"; foreach(m; match(abc, regex(r"\b\w"))) { writefln("between: '%s'", abc[last_pos + last_size..m.pre.length]); writefln("%s[%s]%s", m.pre, m.hit, m.post); last_size = m.hit.length; last_pos = m.pre.length; } writefln("between: '%s'", abc[last_pos + last_size..$]); } // Prints: // between: '' // [t]he quick brown fox jumped over the lazy dog // between: 'he ' // the [q]uick brown fox jumped over the lazy dog // between: 'uick ' // the quick [b]rown fox jumped over the lazy dog // between: 'rown ' // the quick brown [f]ox jumped over the lazy dog // between: 'ox ' // the quick brown fox [j]umped over the lazy dog // between: 'umped ' // the quick brown fox jumped [o]ver the lazy dog // between: 'ver ' // the quick brown fox jumped over [t]he lazy dog // between: 'he ' // the quick brown fox jumped over the [l]azy dog // between: 'azy ' // the quick brown fox jumped over the lazy [d]og // between: 'og' If you replace '\b\w' with '\s' it should help illuminate the way it works: between: 'the' the[ ]quick brown fox jumped over the lazy dog between: 'quick' the quick[ ]brown fox jumped over the lazy dog between: 'brown' the quick brown[ ]fox jumped over the lazy dog between: 'fox' the quick brown fox[ ]jumped over the lazy dog between: 'jumped' the quick brown fox jumped[ ]over the lazy dog between: 'over' the quick brown fox jumped over[ ]the lazy dog between: 'the' the quick brown fox jumped over the[ ]lazy dog between: 'lazy' the quick brown fox jumped over the lazy[ ]dog between: 'dog'
Re: Semicolon can be left out after do-while
On 04/13/2011 07:44 AM, Emil Madsen wrote: On 13 April 2011 14:36, Steven Schveighoffer mailto:schvei...@yahoo.com>> wrote: On Tue, 12 Apr 2011 18:00:40 -0400, spir mailto:denis.s...@gmail.com>> wrote: On 04/12/2011 11:51 PM, Steven Schveighoffer wrote: On Tue, 12 Apr 2011 17:21:57 -0400, spir mailto:denis.s...@gmail.com>> wrote: On 04/12/2011 09:21 PM, Steven Schveighoffer wrote: int main(){ int a,b; do{ scanf("%d %d",&a,&b); }while(ahttp://www.digitalmars.com/d/2.0/statement.html#DoStatement) [...] I think the grammar should be changed... yop! This is almost as bad as go's requirement for if statement opening block to be on the same line... why? I like Go's syntactuc diffs. (except for its "multi-for") in Go, this: if(x) { gosWriteRoutineThatIDontKnowTheSyntaxOf("hello") } is equivalent to this in D: if(x) { } writeln("hello"); This is frankly unforgivable IMO. Of course it's fixable, but the attitude that "the coder should know better" doesn't really make me comfortable with it. And I hate the "brace on the same line" format (but this of course is not a real argument against it). Oh, that's what you meant! I find this a Good Thing, in that it enforces one bracing style (the right one, that does not eats one more line for just a '{'). No, it doesn't enforce anything. The above compiles and runs. What it does is introduce subtle bugs. The way to fix it is to make the above an error. About knowing or not about this (non/mis/-)feature, it's written down, and clearly, in all Go docs I've read. And one cannot miss it for very long anyway ;-) I know that if(xyz); is not *ever* what I meant, but in C it compiles. However, in D, it tells me I shouldn't do that. What results is less bugs because I can't make that mistake without the compiler complaining. I'm not saying that the spec isn't well defined, or the manual isn't clear, what I'm saying is, the attitude reflected in the rule is that greater burden is put on the developer to make sure they follow the rules without compiler enforcement. It makes me want to not use Go. And in fact, I will probably never use it as long as this rule is in place. Maybe, if not done already, a line starting with an opening brace should generate a parsing error. Typically this is used to create a new scope in C/D/Java/C#. This allows declaring temporary variables, not sure how it is in Go, but I'd assume something similar. -Steve Does D throw an error at; if(expression && expression)*; *or only at if(expression); Because you could actually use the first one, alike this: #include bool test() { printf("test\n"); return false; } bool test2() { printf("test2\n"); return true; } int main() { if(test() && test2()); } Output = "test" if test returns true, then: Output = "test" + "test2" Simply because its conditional, and if the first one fails, why bother evaluating the rest? -- // Yours sincerely // Emil 'Skeen' Madsen I would argue that the more correct way to do this would be to separate the statements that are used in the condition from the statements that are not used in the condition. if(test()) test2(); Since test2's return statement isn't used for anything means to me that it doesn't belong in the conditional statement.
Re: "Before and after" in contracts?
On 04/11/2011 06:05 AM, Magnus Lie Hetland wrote: I'd like to write a contract for a method to ensure that a given attribute does not decrease when calling the method. In order to do that, I need to store the "before" value, and compare it to the after value. My first intuition was to declare a variable in the in-block, and then access that in the out-block. No dice, it seems. I tried declaring one in the body (with a version(unittest) qualifier). Still no dice. I ended up using a separate *attribute* for this, which seems particularly ugly to me. Is it philosophically "wrong" to write stateful "before/after" contracts like this? If not, can it be done in a less ugly manner? (Or should I just learn to like this way of doing it?) I don't know if I can speak to the philosophical points here, but you can put your attribute declarations in a version block, and as long as the usage of that attribute is only used when that version is used, you should be fine.
Re: time_t to simple date string conversion
On 04/05/2011 03:40 PM, Steven Schveighoffer wrote: On Tue, 05 Apr 2011 17:24:11 -0400, Kai Meyer wrote: I'm reading documentation on std.datetime, and it appears there are added features that I don't have in 2.51 (Linux). Did features like 'SysTime' get added after 2.51? Does anybody have a one-liner to convert a time_t to a date string that should work for me? auto t = time(); auto systime = SystemTime(unixTimeToStdTime(t)); // to system time from there, you have many options to create the right string. You can start with just writing it (via toString): writeln(systime); There's also: http://www.digitalmars.com/d/2.0/phobos/std_datetime.html#toSimpleString http://www.digitalmars.com/d/2.0/phobos/std_datetime.html#toISOString http://www.digitalmars.com/d/2.0/phobos/std_datetime.html#toISOExtendedString and doing it directly: writefln("%s/%s/%s", t.month, t.day, t.year); Don't see a way to print the month in text format, but maybe I'm overlooking it. -Steve Ok, that works. Thanks :)
Re: time_t to simple date string conversion
On 04/05/2011 03:59 PM, Jonathan M Davis wrote: I'm reading documentation on std.datetime, and it appears there are added features that I don't have in 2.51 (Linux). Did features like 'SysTime' get added after 2.51? Does anybody have a one-liner to convert a time_t to a date string that should work for me? std.datetime was completely revamped with 2.52. What existed from in 2.51 has little to do with what's in 2.52, and it wasn't even publically documented anyway. So, if you're using 2.51, you're still stuck using std.date, which is rather broken. I'd definitely recommend that you upgrade to 2.52 if you're still using 2.51. If you're using 2.51 and for some reason can't upgrade, then I'd recommend that you just use the standard C functions. That would be less error-prone than trying to use std.date, which is scheduled for deprecation anyway. And assuming that you can't upgrade, if the reason for that is because you're installed dmd with your distro, I'd recommend uninstalling it and just downloading the zip file from the main site. Your distro is not likely to keep dmd as up-to-date as downloading it yourself will, and it improves too quickly to stick with a version which is months old. It's easy to use the zip. All you have to do is unzip it to wherever you want to unzip it, and the add /path/to/unzipped/dmd2/linux/bin to your path, and it works (unless you're on a 64-bit box, then you need to install certain 32-bit packages, but it's a fairly short list, and if your distro actually includes a package for dmd, then it should be easy to figure out what they are by looking at the dependencies for that package). In any case, prior to dmd 2.52, there effectively was no std.datetime. The date stuff was the rather buggy std.date, which is now scheduled for deprecation. So, either you need to upgrade to 2.52, use std.date, or use the standard C functions. - Jonathan M Davis So who do I bug to update the RPM build on the Downloads page? The zip and windows versions are 2.52, but the Linux RPM version is 2.51.
time_t to simple date string conversion
I'm reading documentation on std.datetime, and it appears there are added features that I don't have in 2.51 (Linux). Did features like 'SysTime' get added after 2.51? Does anybody have a one-liner to convert a time_t to a date string that should work for me? -Kai Meyer
Re: Array operation doesn't check array bounds
On 04/03/2011 05:06 PM, Jonathan M Davis wrote: On 2011-04-03 04:10, simendsjo wrote: int[] a = [1,2,3]; int[4] b; assert(b == [0,0,0,0]); b = a[] * 3; // oops... a[] * 3 takes element outside a's bounds assert(b[$-1] == 0); // fails.. last element is *(a.ptr+3) * 3 Array bounds checking is done on code which is not compiled with the - noboundscheck flag and which is either not built with -release or is @safe. I assume that you're not compiling with -noboundscheck (which turns off all array bounds checking). So, you're likely compiling with -release on code which isn't @safe. @system is the default, so unless you've marked your code @safe or you're not compiling with -release, I wouldn't expect there to be any bounds checking. If you want to guarantee that there's always bounds checking, then you need to mark your code @safe and not use -noboundscheck. However, given how little of Phobos is currently @safe or @trusted, odds are that trying to mark your code @safe will get _really_ annoying at this point. And to fix that, we'd likely need conditional @safe and conditional @trusted for the same reasons that we need conditional pure. And those haven't been taken care of yet (there isn't even an official plan to as far as I know - though hopefully there will be). - Jonathan M Davis This is the really verbose answer to the question I thought you were asking as well. I think this problem is better expressed like this: import std.stdio; void main() { int[] a = [1,2,3]; int[4] b; int[4] c = [0,1,2,3]; int[5] d = [0,1,2,3,4]; assert(b == [0,0,0,0]); b = c[] * 3; // like foreach(val; c) b.append(val*3); writef("%s %s %s\n", a, b, c); b = a[] * 3; // No error writef("%s %s %s\n", a, b, c); b = a[]; // object.Exception: lengths don't match for array copy writef("%s %s %s\n", a, b, c); writef("%s\n", a[] * 3); // bounds.d(15): Error: Array operation a[] * 3 not implemented assert(b[$-1] == 0); } I think bearophile addressed this, but I can't quite tell. So now I'm curious, why does the multiply operation break the bounds check? Also, why does it fail to print? The result can be stored in another array, so I would think it would print.
Re: How to spawn processes while keeping the parent process open ?
On 04/03/2011 07:31 AM, Tarun Ramakrishna wrote: Hi, Apparently std.process.exec (D2.052/windows) doesn't work the way the documentation describes. It terminates the parent process. Is there a way to keep the parent process open in D ? I also vaguely remember seeing some mails on this list about an improved process library in D. Any tips appreciated, Thanks, Tarun I think exec is meant to replace the current running process with the new one. I think the one you want is either "shell" or "system". http://www.digitalmars.com/d/2.0/phobos/std_process.html
Re: Contracts or Exceptions?
On 03/29/2011 09:32 PM, Ali Çehreli wrote: On 03/29/2011 03:40 PM, Kai Meyer wrote: > I was given two words of advice on exceptions: > "Use exceptions for the exceptional" > "Use exceptions only for the exceptional" Those advices are given by wise people: they are wise only because they leave the definition as vague as "exceptional." :) Ya, now that I'm thinking about it a little more, we were talking about what sort of things you can do to increase performance. This was actually pretty far down the list, after considering things like profiling, improving algorithms, using built-in types instead of classes, ect. Exceptions are a little more expensive than condition statements. And what do we do for the "not so exceptional"? Do we return error codes? So the function implementation will be complicated and the caller code will be complicated. You're right. I would consider those complications only if the optimisation I'm after justifies them. For example, if our profiler indicates that the function is running slowly due to handling a lot of exceptions (which probably won't be the first thing the profiler finds is running slow), we could use conditional statements to speed things up a bit. if (good data) do work else report "can't do work" Would be faster than: try do work catch report "can't do work" I'll also add that the same person who gave me this advice also likes to say "Premature optimisation is the root of all evil." Exceptions are a great tool to eliminate the need for error codes. Here is what I follow: - Functions have specific tasks to do; if those tasks cannot be accomplished, the function must throw. In some cases the function can continue, but that behavior must be documented. For example, if an HTML library function is responsible for making HTML headers, of which only the levels in the range of 1-6 are valid, that function may throw when the level is outside of the valid range, for in that case it cannot "make an HTML header"; or it can document that if the level is outside of the range, 1 or 6 will be used. - Catch exceptions only when there is a sensible thing to do at that level: log an error, skip that operation, go back to the user with an error code, take corrective action, etc. Disclaimer: That is what I follow in C++ code. I don't have experience with exception safety in D. I don't know issues that may be specific to D. Ali Thanks for your insight Ali :) I'm not sure D's exceptions are much different than C++'s. I think you're right on.
Re: Contracts or Exceptions?
On 03/30/2011 08:25 AM, Kagamin wrote: Kai Meyer Wrote: do all the checking before hand. Arrays are a good example. When not in -release mode, array boundaries are checked upon every access to the array, and an exception is thrown if access goes out of bounds. In -release mode, if you go out of bounds you get a segfault. No, you get a remote root vulnerability. Sure, but the point is that arrays can be used in a way that performs as fast as possible, therefore it becomes the programmer's job to ensure that all access to the array is within bounds, which is faster than making the array check itself every time.
Re: Contracts or Exceptions?
On 03/29/2011 12:40 PM, Mike Linford wrote: Hello, So I'm writing a function for a library. It takes a struct as an argument. The struct's fields can't just be any old values, though. The function won't work if some of the fields are weird. It could return an erroneous value, or even crash. The thing is, though, that I can't tell whether the best approach is to use an in-contract or throw an exception if it doesn't pass my test. What would you guys recommend? I was given two words of advice on exceptions: "Use exceptions for the exceptional" "Use exceptions only for the exceptional" Meaning, if you expect something to fail frequently, using a try/catch is much more expensive than an if/else. "The exceptional" is something that should rarely ever occur, like running out of memory. For contracts, they are usually meant as a developer tool to warn them when that they will be in no-man's land if they attempt to proceed any further. They are, therefore, not compiled in when you pass the D compiler the -release flag. I don't think that contracts and exceptions are mutually exclusive. They provide two different safeguards. One is a tool to aid in the development process, one is a tool to safeguard against exceptional run-time scenarios. However, I think if I rephrase your question a little bit, it might provide you what I think you're after. I'm making an assumption here, so I may be way off the mark. "Who's responsibility is it to check whether or not the data passed into the function is valid? Should I accept whatever the user wants to pass in, and let them know when it's invalid, or should I trust that the user is sending in good data?" I think that's a choice for you to make. Contract programming is often used to put the burden of validation on the user of the library (meaning programmer writing software taht uses your library). Exceptions could be used to indicate that the library writer is accepting responsibility for validating the data before using it. But validating data is not the only reason to use exceptions, and it's not unusual for a library to skip all validations and force the user to do all the checking before hand. Arrays are a good example. When not in -release mode, array boundaries are checked upon every access to the array, and an exception is thrown if access goes out of bounds. In -release mode, if you go out of bounds you get a segfault. This is one example of giving the user (programmer) of arrays the responsibility to check boundaries so that the library can focus on being fast. I think the choice comes down to a balance between performance, responsibility, and maintainability. (Oh, and you'll usually get it wrong the first time, so don't be sad.)
Re: Little quiz
On 03/24/2011 06:50 PM, bearophile wrote: A little quiz for people here: guess the output of this little D2 program (it compiles correctly and doesn't crash at run time, so it's a fair question): import std.typecons: tuple; import std.c.stdio: printf; auto foo() { printf("foo\n"); return tuple(1, 2); } void main() { foreach (x; foo().tupleof) printf("%d\n", x); } Bye, bearophile That's pretty cool :) Seems like we should be able to expect the same behavior in all of these, but that doesn't appear to be the case at all. import std.typecons: tuple; import std.c.stdio: printf; auto foo() { printf("foo\n"); return tuple(1, 2); } void main() { printf("-\n"); foreach (x; foo().tupleof) printf("%d\n", x); printf("-\n"); auto f = foo(); printf("-\n"); foreach (x; f.tupleof) printf("%d\n", x); printf("-\n"); auto f2 = foo().tupleof; printf("-\n"); foreach (x; f2) printf("%d\n", x); printf("-\n"); }
Re: clear()
On 03/25/2011 01:10 PM, Dr.Smith wrote: To empty many arrays of various types, rather than: clear(arr1); clear(arr2); ... clear(arrN); is there something like: clear(ALL); No, but perhaps you can do a: foreach(a; ALL) a.clear() But that would require you having an iterable sequence that contains all of your arrays, which may or may not be worth your time to explore. Also, after "clear(arr)", will "arr ~= value" assign starting from element 0? Yes
Re: fun with properties
On 03/23/2011 10:09 AM, teo wrote: On Wed, 23 Mar 2011 08:28:46 -0600, Kai Meyer wrote: On 03/23/2011 06:48 AM, teo wrote: How can I use properties with increment/decrement and +=/-= operators? I did following tests (the errors are from dmd v2.052): class T { private int _x; @property public int x() { return _x; } } void main() { int[] a; // case #1.1 a.length++;// Error: a.length is not an lvalue // case #1.2 a.length += 1; // Ok auto t = new T(); // case #2.1 t.x++; // Error: t.x() is not an lvalue // case #2.2 t.x += 1; // Error: 't.x' is not a scalar, it is a @property int() // Error: incompatible types for ((t.x) += (1)): '@property int()' and 'int' // case #2.3 t.x()++;// Error: t.x() is not an lvalue // case #2.4 t.x() += 1; // Error: t.x() is not an lvalue } Basically I want to change the value of a member variable, which is accessed only through a property. It looks like that is partially possible with the length property of dynamic arrays although they probably are implemented in a different way. You need a "write" property: @property { public int x() { return _x; } // Read property public void x(int x1) { _x = x1; } // Write property } I've already tried that, but to no avail. I am getting the errors stated above. Can you give me a complete working example please? Sorry, you're right. I don't think properties are done, especially given these features don't work as expected.
Re: Want to help DMD bugfixing? Write a simple utility.
that work. The Q's are how hard is it to get the symbols from the linker and then how hard is it to match those to source. IIRC there are functions in phobos to convert to/from symbol names, so if the app had sufficient lexing and parsing capability it could match on those. That would require a full-blown D lexer and parser. - Jonathan M Davis Why are we talking about having to recreate a full-blown lexer and parser when there has to be one that exists for D anyway? This is sounding more and more like you're asking the wrong crowd to solve a problem. To do it right, the people who have access to the real D lexer and parser would need to write this utility, and in some ways, it's already written since compiling with out a -unittest flag already omits all the unittests. So I'm a bit confused about two things. 1) Why ask the wrong people to write the tool in the first place? 2) Why are we the wrong people any way? -Kai Meyer
Re: fun with properties
On 03/23/2011 06:48 AM, teo wrote: How can I use properties with increment/decrement and +=/-= operators? I did following tests (the errors are from dmd v2.052): class T { private int _x; @property public int x() { return _x; } } void main() { int[] a; // case #1.1 a.length++;// Error: a.length is not an lvalue // case #1.2 a.length += 1; // Ok auto t = new T(); // case #2.1 t.x++; // Error: t.x() is not an lvalue // case #2.2 t.x += 1; // Error: 't.x' is not a scalar, it is a @property int() // Error: incompatible types for ((t.x) += (1)): '@property int()' and 'int' // case #2.3 t.x()++;// Error: t.x() is not an lvalue // case #2.4 t.x() += 1; // Error: t.x() is not an lvalue } Basically I want to change the value of a member variable, which is accessed only through a property. It looks like that is partially possible with the length property of dynamic arrays although they probably are implemented in a different way. You need a "write" property: @property { public int x() { return _x; } // Read property public void x(int x1) { _x = x1; } // Write property } As for the dynamic array length property: void main() { int[] a; ++a.length; // Works a.length += 1; // Works a.length++; // Error: a.length is not an lvalue } I don't get why the error on a.length++ either. I'm curious about the answer.
Re: Want to help DMD bugfixing? Write a simple utility.
On 03/19/2011 06:11 PM, Don wrote: Here's the task: Given a .d source file, strip out all of the unittest {} blocks, including everything inside them. Strip out all comments as well. Print out the resulting file. Motivation: Bug reports frequently come with very large test cases. Even ones which look small often import from Phobos. Reducing the test case is the first step in fixing the bug, and it's frequently ~30% of the total time required. Stripping out the unit tests is the most time-consuming and error-prone part of reducing the test case. This should be a good task if you're relatively new to D but would like to do something really useful. -Don Is there a copy of the official D grammar somewhere online? I wrote a lexer for my Compiler class and would love to try and apply it to another grammar. -Kai Meyer
Re: How do I iteratively replace lines in a file?
On 03/20/2011 09:46 AM, Andrej Mitrovic wrote: Yeah, I've already done exactly as you guys proposed. Note however that `inputfile` and `outputfile` should be declared inside the foreach loop. Either that or you have to call `close()` explicitly. If you don't do that, file handles don't get released, and you'll eventually get back a stdio error such as "too many file handles opened". You could loose files this way. I know this because it just happened yesterday while testing. :p Anywho, I needed a quick script to append a semicolon to import lines because I managed to screw up some files when using sed to replace some lines. It's a quick hack but worked for me: import std.stdio; import std.file; import std.stdio; import std.path; import std.string; void main() { File inputfile; File outputfile; string newname; foreach (string name; dirEntries(r".", SpanMode.breadth)) { if (!(isFile(name)&& getExt(name) == "d")) { continue; } newname = name.idup ~ "backup"; if (exists(newname)) { remove(newname); } rename(name, newname); inputfile = File(newname, "r"); outputfile = File(name, "w"); foreach (line; inputfile.byLine) { if ((line.startsWith("private import") || line.startsWith("import"))&& !line.endsWith(",")&& !line.endsWith(";")) { outputfile.writeln(line ~ ";"); } else { outputfile.writeln(line); } } inputfile.close(); outputfile.close(); } foreach (string name; dirEntries(r".", SpanMode.breadth)) { if (getExt(name) == "dbackup") { remove(name); } } } Funny, I would have just fixed it with sed. sed -ir 's/^(import.*)/\1;' *.d Infact, I think sed is actually a great example of an application that you apply a search and replace on a per-line basis. I'd be curious if somebody knows how their '-i' flag (for in-place) works. Based on the man page, I'll bet it opens the source read-only, and opens the destination write-only like Andrej's example. -i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if extension supplied) The SUFFIX option just renames the original instead of deleting at the end.
Re: How do I iteratively replace lines in a file?
On 03/19/2011 05:51 PM, Andrej Mitrovic wrote: I'm trying to do something like the following: File inputfile; foreach (string name; dirEntries(r".\subdir\", SpanMode.shallow)) { if (!(isFile(name)&& getExt(name) == "d")) { continue; } inputfile = File(name, "a+"); foreach (line; inputfile.byLine) { if (line == "import foo.d") { inputfile.write("import bar.d"); // or ideally `line = "import bar.d"` } } } That obviously won't work. I think I might need to use the `fseek` function to keep track of where I am in the file, or something like that. File I/O in D is no fun.. The only problem with your approach that a "line" is an abstract concept. In a filesystem, there are only blocks of bytes. When you write (flush) a byte to a file, the file transaction is actually an entire block at a time (ext3 defaults to a 4k block, for example.) Lines are just an array of bytes. When dealing with (relatively) fast memory, modifying a line is pretty transparent. If you open a 1GB file and add bytes at the very beginning, the filesystem is quite likely to write out the entire file again. I would suggest you write out to a temporary file, and then move the file on top of the original file. foreach(name ...) { inputfile = File(name, "r"); outputfile = File("/tmp/" ~ name, "a"); foreach(line ...) { do something to line outputfile.write(line); } outputfile.close(); rename("/tmp" ~ name, name); } This will allow you to manipulate line by line, but it won't be in-place. This is the type of approach that a lot of text editors take, and a very common work around. If you were to encounter a language that allows you to read and write lines iteratively and in-place like this in a file, I'll bet you they are writing your changes to a temp file, and moving the file over the top of the original at the end (perhaps when you close()).
Re: Reading a line from stdin
On 03/16/2011 07:54 AM, Ali Çehreli wrote: On 03/16/2011 05:49 AM, Kagamin wrote: Ali ǥhreli Wrote: The following program may be surprising to the novice: import std.stdio; void main() { write("What is your name? "); string name = readln(); writeln("Hi ", name, "!"); } What if the user typed leading spaces? Will the program operate as you expect? I would not like the leading spaces either, and that's another issue: contrary to readln(), readf() leaves the newline character in the input. I was about to start adopting the guideline of using " %s" (note the space) when reading formatted unless there is a reason not to. Most of the time the newline left from the previous input has nothing to do with the next read. Otherwise the following program gets stuck: import std.stdio; void main() { int i, j; readf("%s%s", &i, &j); } As a result, my current guideline is "put a space before every format specifier": readf(" %s %s", &i, &j); This is a departure from C's scanf but is more consistent. I don't want to accept and teach buggy behavior and that's why I asked on the D forum. Unfortunately I failed to attract interest there. After accepting the above, I wanted to readf() lines too: import std.stdio; void main() { string s; readf(" %s", &s); writeln(s); } As another departure from C, readf() does not stop at the first whitespace. It reads until the end of the input. Ok, I like that behavior but it's not useful for "What is your name? " like inputs. So it led me to readln(). I don't have a problem with whitespace being left in the line, I just want to know whether that's the intended or accepted behavior. Ali I think there are two issues here. First, I think is perfectly reasonable to let the programmer use a simple mechanism like "string.chomp(stdin.readline())" or simply "chomp(readln())" when they don't want the new line. Second, D doesn't seem to have a graceful way of reading an endless stream of delimited by delimiting character>. I think readf is rigid, and works great in some cases. I would greatly appreciate something more flexible like C++'s extraction operator (operator>>) though. For example: int i = 0; while(cin >> i) { //Do something } // Done doing something
Re: Best way in D2 to rotate a ubyte[4] array
On 03/09/2011 04:25 PM, bearophile wrote: Tom: What is the most efficient way of implement a rotation of ubyte[4] array? By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] Two versions, I have done no benchmarks so far: import std.c.stdio: printf; union Four { ubyte[4] a; uint u; } void showFour(Four f) { printf("f.u: %u\n", f.u); printf("f.a: [%d, %d, %d, %d]\n", cast(int)f.a[0], cast(int)f.a[1], cast(int)f.a[2], cast(int)f.a[3]); } void main() { Four f; f.a[] = [1, 2, 3, 4]; showFour(f); f.u = (f.u<< 8) | (f.u>> 24); showFour(f); printf("\n"); // alternative f.a[] = [1, 2, 3, 4]; uint u2 = f.u; showFour(f); printf("u2: %u\n", u2); asm { rol u2, 8; } f.u = u2; showFour(f); } /* dmd -O -release test.d __Dmain comdat pushEBP mov EBP,ESP sub ESP,8 push4 mov EAX,offset FLAT:_D12TypeInfo_xAh6__initZ push4 push3 push2 push1 push4 mov dword ptr -8[EBP],0 pushEAX callnear ptr __d_arrayliteralT add ESP,018h pushEAX lea EAX,-8[EBP] pushEAX callnear ptr _memcpy mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,-8[EBP] mov ECX,-8[EBP] shl EAX,8;<= shr ECX,018h or EAX,ECX mov -8[EBP],EAX mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,offset FLAT:_DATA[024h] pushEAX callnear ptr _printf mov EAX,offset FLAT:_D12TypeInfo_xAh6__initZ push4 push4 push3 push2 push1 push4 pushEAX callnear ptr __d_arrayliteralT add ESP,018h pushEAX lea EAX,-8[EBP] pushEAX callnear ptr _memcpy mov EAX,-8[EBP] mov -4[EBP],EAX mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,offset FLAT:_DATA[028h] pushdword ptr -4[EBP] pushEAX callnear ptr _printf add ESP,024h rol -4[EBP],8 ;<= mov EAX,-4[EBP] mov -8[EBP],EAX mov EAX,-4[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov ESP,EBP pop EBP ret */ In theory a C/C++/D compiler has to compile an expression like (x<< 8)|(x>>24) with a ROL instruction, in practice DMD doesn't do it. Months ago I have asked the two (four in X86) roll instructions to be added to the Phobos core intrinsics module, but I am not sure what Walter answered me. Bye, bearophile I love it. I've done a little benchmark that just repeats the rotate left a certain number of times, and then a rotate right a certain number of times. It looks like shifting ( << | >> ) is faster than the process of copying the uint value, shifting it, and copying it back. If I move the assignment for the rol outside of the for loop, the rol is about twice as fast. http://dl.dropbox.com/u/12135920/rotate.d Both are anywhere from 30 to 80 times faster than the slicing method I proposed (also included in the rotate.d file). -- Rotating static array left to right 500 times Finished in1971.46 milliseconds Rotating static array right to left 500 times Finished in1987.60 milliseconds Rotating dynamic array left to right 500 times Finished in1932.40 milliseconds Rotating dynamic array right to left 500 times Finished in1981.71 milliseconds Shifting Union left to right 500 times Finished in 33.46 milliseconds Shifting Union right to left 500 times Finished in 34.26 milliseconds Rolling Union left to right 500 times Finished in 67.51 milliseconds Rolling Union right to left 500 times Finished in 67.47 milliseconds Rolling Union left to right 500 times with assignment with temporary variable outside of the loop Finished in 28.81 milliseconds Rolling Union right to left 500 times with assignment with temporary variable outside of the loop Finished in 25.57 milliseconds
Re: Best way in D2 to rotate a ubyte[4] array
On 03/09/2011 03:41 PM, Tom wrote: What is the most efficient way of implement a rotation of ubyte[4] array? By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] TIA, Tom; I don't know of anything more efficient than: ubyte[4] bytes = [1,2,3,4]; bytes = bytes[$-1] ~ bytes[0..$-1]; // Rotate left bytes = bytes[1..$] ~ bytes[0]; // Rotate right Both static arrays and dynamic arrays (ubyte[] bytes = [1,2,3,4];) perform about the same between 1 and 10 milling rotations in either direction. I think a temporary array might be created for the rhs, and then have the values of the rhs array copied to the lhs array, but I don't know. With static arrays, I'm not sure there would be a way to get around it with out at least a temporary value for the one that's moving between the first and last positions.
Re: Iterating over 0..T.max
On 03/09/2011 09:09 AM, Magnus Lie Hetland wrote: In a (template) data structure I'm working on, I had the following thinko: auto a = new T[n]; foreach (T i, ref e; a) { e = i; } Then I instantiated it with T=bool, and n=256. Infinite loop, of course -- the problem being that i wraps around to 0 after the last iteration. Easily fixed, and not that much of a problem (given that I caught it) -- I'll just use e = cast(T) i. (Of course, even with that solution, I'd get wrap problems if n=257, but I just want to make sure I allow T.max as a size.) But I'm wondering: given D's excellent valua range propagations and overflow checking, would it be possible to catch this special case (i.e., detect when the array can be too long for the index type)? Or are any other safeguards possible to prevent this sort of thing? I don't see how that works in dmd2, and I don't have much experience with dmd1, so I'll admit that this may be different on dmd1. I get compilation errors with your code: import std.stdio; void main() { make_new!(bool)(256); } void make_new(T)(size_t n) { auto a = new T[n]; foreach (T i, ref e; a) { e = i; } } This gives me: tmax.d(12): Error: operation not allowed on bool 'i' tmax.d(5): Error: template instance tmax.make_new!(bool) error instantiating As far as I understand, a foreach over an array makes the first value (i) a uint for the index, and the second value (e) a copy of the value in the array (in our case a bool). import std.stdio; void main() { make_new!(bool)(1); } void make_new(T)(size_t n) { auto a = new T[n]; writef("%s\n", typeof(a).stringof); foreach (i,e; a) { writef("%s\n", typeof(i).stringof); writef("%s\n", typeof(e).stringof); } } /* Output: bool[] uint bool */ But to the question about boundaries, 'i' is a uint (size_t), and on a 4GB machine, I can't call "auto a = new bool[size_t.max];". The program segfaults. size_t.max / 2 for a size gives me "Memory allocation failed". size_t.max / 4 works fine. I'm not sure how to get a program to do what you describe.
Re: Dynamic array void initialization
On 03/08/2011 05:42 PM, Kai Meyer wrote: On 03/08/2011 02:34 PM, Tom wrote: import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom; Any reason you don't just do this: S[] ss; ss.reserve(5) foreach(i; 0..i) ss ~= S(1, 2); I think that would not do default initialization on any of the elements, and it would ensure that the dynamic array is own "grown" once. Sorry, foreach(i; 0..5) That's what I get for writing code with out trying to run it
Re: Dynamic array void initialization
On 03/08/2011 02:34 PM, Tom wrote: import std.stdio; struct S { int i; int j; } int main(string[] args) { S[] ss = void; ss.length = 5; foreach (ref s; ss) s = S(1, 2); return 0; } Is the above code correct? (it doesn't work... it blows away or just give and access violation error). I need to create a dynamic array of some struct, but don't want defer contained elements initialization (for performance reasons). Tom; Any reason you don't just do this: S[] ss; ss.reserve(5) foreach(i; 0..i) ss ~= S(1, 2); I think that would not do default initialization on any of the elements, and it would ensure that the dynamic array is own "grown" once.
Re: Help learning how to interface with c(++)
On 03/07/2011 08:57 AM, Kai Meyer wrote: On 03/05/2011 06:24 AM, Kagamin wrote: Kai Meyer Wrote: I can't seem to get this to work right: gcc -m32 -shared -fPIC Test.cpp -o libTest.so g++ -m32 test_c.cpp -L. -lTest -o test_c wine htod.exe Test.h Test.d dmd test_d.d Test.d -L-L. -L-lTest -oftest_d test_d.o: In function `_Dmain': Test.d:(.text._Dmain+0x20): undefined reference to `increment' collect2: ld returned 1 exit status --- errorlevel 1 make: *** [test_d] Error 1 The resulting test_c binary from g++ works as intented (With either LD_LIBRARY_PATH="." or LD_RUN_PATH="."): $ ./test_c Count = 0 Count = 1 $ ldd test_c linux-gate.so.1 => (0x00ad1000) libTest.so (0x005b9000) try non-shared libTest, dmd prefers single executable compilations. Is that the only option? I know it's possible to link to external c libraries, and I'd like to learn how. So I monkeyed around a little bit, and found out that if I change "extern (C)" to "extern (C++)", the library links correctly and the program runs. That lead me to believe that if I added the "-cpp" option to htod.exe, it would generate extern(C++) functions. But I got a blank Test.d file doing it that way. So, gcc created a libTest.so with a function in it, and dmd only finds the function with extern(C++) and not with extern(C). Now I'm just confused, yet pleased something worked. -Kai Meyer
Re: Help learning how to interface with c(++)
On 03/05/2011 06:24 AM, Kagamin wrote: Kai Meyer Wrote: I can't seem to get this to work right: gcc -m32 -shared -fPIC Test.cpp -o libTest.so g++ -m32 test_c.cpp -L. -lTest -o test_c wine htod.exe Test.h Test.d dmd test_d.d Test.d -L-L. -L-lTest -oftest_d test_d.o: In function `_Dmain': Test.d:(.text._Dmain+0x20): undefined reference to `increment' collect2: ld returned 1 exit status --- errorlevel 1 make: *** [test_d] Error 1 The resulting test_c binary from g++ works as intented (With either LD_LIBRARY_PATH="." or LD_RUN_PATH="."): $ ./test_c Count = 0 Count = 1 $ ldd test_c linux-gate.so.1 => (0x00ad1000) libTest.so (0x005b9000) try non-shared libTest, dmd prefers single executable compilations. Is that the only option? I know it's possible to link to external c libraries, and I'd like to learn how.
Re: in/out with -release
On 03/05/2011 11:14 AM, Lars T. Kyllingstad wrote: On Sat, 05 Mar 2011 18:12:30 +, Lars T. Kyllingstad wrote: On Sat, 05 Mar 2011 10:15:48 -0700, user wrote: On 03/04/2011 09:22 PM, Jonathan M Davis wrote: On Friday 04 March 2011 20:14:32 Kai Meyer wrote: I have an 'enforce' function call in an 'in' block for a function. When I compile with "-release -O -inline", the in/out blocks appear to be skipped. It's a simple verification for a dynamic array to not have a length of 0. In debug mode, the test condition hits the enforce in the 'in' block, but in release mode it does not. In both release and debug mode, the same exact enforce function works properly. So am I to understand that -release will skip in/out blocks entirely? Of course. It uses asserts. asserts are disabled in -release. Asserts are for debugging, testing, and verifying code when developing, not for code which is released. So, you get the benefit of the test when you don't have -release and the benefit of speed when you do have -release. If an assertion fails, your code logic is invalid. It's for validating your code, not user input or whatnot. enforce, on the other hand, is not a language primitive. It's not intended for testing or debugging. It's intended to be used in production code to throw an exception when its condition fails. If an enforce fails, that generally means that you had bad input somewhere or that an operation failed or whatnot. It's not intended for testing the logic of your code like assert is intended to do. It's simply a shorthand way to throw an exception when your program runs into a problem. - Jonathan M Davis I don't think I understand your response entirely. I understand that asserts are disabled in -release mode. I understand that enforce is a function that comes with std.exception, and the code isn't hard to follow. What I'm confused about is the in block, and why it is skipped in -release mode. You say "It uses asserts." I didn't put an assert in my in block, I put an enforce. So I'm guessing that you are indicating that the in block is treated like an assert, and is disabled with the -release flag. But I think after reading your post you've helped clarify that what I'm checking (that you can't pop an empty stack) based on user input is something I should be checking with an enforce inside the function, and not an assert or enforce inside the in block. I still think I would like it if you could be a little more explicit about the in/out blocks. Are they always disabled entirely (skipped) with -release, or just certain things? Thanks for your help! -Kai Meyer That's right. in, out and invariant blocks are not included in release mode. -Lars It's documented here, by the way: http://www.digitalmars.com/d/2.0/dmd-linux.html#switches (Scroll down to -release.) -Lars All very welcome responses. Thanks for your time :) Got lots of reading to do. -Kai Meyer
in/out with -release
I have an 'enforce' function call in an 'in' block for a function. When I compile with "-release -O -inline", the in/out blocks appear to be skipped. It's a simple verification for a dynamic array to not have a length of 0. In debug mode, the test condition hits the enforce in the 'in' block, but in release mode it does not. In both release and debug mode, the same exact enforce function works properly. So am I to understand that -release will skip in/out blocks entirely?
Help learning how to interface with c(++)
I can't seem to get this to work right: gcc -m32 -shared -fPIC Test.cpp -o libTest.so g++ -m32 test_c.cpp -L. -lTest -o test_c wine htod.exe Test.h Test.d dmd test_d.d Test.d -L-L. -L-lTest -oftest_d test_d.o: In function `_Dmain': Test.d:(.text._Dmain+0x20): undefined reference to `increment' collect2: ld returned 1 exit status --- errorlevel 1 make: *** [test_d] Error 1 The resulting test_c binary from g++ works as intented (With either LD_LIBRARY_PATH="." or LD_RUN_PATH="."): $ ./test_c Count = 0 Count = 1 $ ldd test_c linux-gate.so.1 => (0x00ad1000) libTest.so (0x005b9000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x4970f000) libm.so.6 => /lib/libm.so.6 (0x4955b000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x49587000) libc.so.6 => /lib/libc.so.6 (0x493ab000) /lib/ld-linux.so.2 (0x4938a000) Any ideas on what I'm doing wrong here? I've dropbox-ed the code if it's helpful. http://dl.dropbox.com/u/12135920/kai_test_c_interface.zip -Kai Meyer
RPM Package management
I would like to get involved with the rpm build process. Who can I contact to get more information on what help I can provide?
Re: datetime fails with undefined reference
== Quote from Jonathan M Davis (jmdavisp...@gmx.com)'s article > On Friday, February 18, 2011 16:27:23 Russel Winder wrote: > > As noted in my earlier email on the other list, I too got this problem. > > Fromn what I can tell 1.066 and 2.051 have dmd.conf files but there is > > no such thing in the 1.067 and 2.052 distributions. So the "out of the > > box" configuration does seem to be "broken". > And as I said in my response to your other message, the proper dmd.conf file > _is_ > in the distributed zip file. So, unless you're dealing with the deb or rpm, > and > they're broken, and I don't know why you wouldn't be seeing a new dmd.conf > with > the 2.052 release. But I don't know what the state of the rpm or deb is. I > just > always use the zip file, which is very simple. > - Jonathan M Davis Ok, I can fix the dmd.conf. Who does manage the RPM packaging? And how can I get a hold of them?
Re: datetime fails with undefined reference
== Quote from Jonathan M Davis (jmdavisp...@gmx.com)'s article > On Friday, February 18, 2011 10:12:09 Kai Meyer wrote: > > Great news! Worked like a champ. Is there documentation somewhere that I > > missed? I would love to be able to answer these questions on my own. I've > > been stumped on this one for a week :( > That should be in the dmd.conf in dmd.2.052.zip. If you're using an old > dmd.conf, that would be the problem. Actually, I wouldn't have expected and > old > dmd.conf to work at all, since the directory structure for the lib folder(s) > was > changed due to the addition of 64-bit. So, I don't know what the deal with > your > setup is. Regardless, make sure that your current dmd.conf is either the most > up-to-date on or at least based on it. Otherwise, you're going to be running > into issues. > - Jonathan M Davis Ok, my dmd.conf that came with the download does not have it in there. The package doesn't claim ownership to /etc/dmd.conf. I removed the rpm package, deleted the old dmd.conf, and installed the rpm again, but the dmd.conf that was generated is exactly the same: [kai@worky ~]$ cat /etc/dmd.conf [Environment] DFLAGS= -I/usr/include/d/dmd/phobos -I/usr/include/d/dmd/druntime/import -L-L/usr/lib Should I just simply add "-L-lrt" to the dmd.conf for now? Or just put it in my make file? Why does the rpm not claim ownership of the config file?: [kai@worky ~]$ rpm -qf /etc/dmd.conf file /etc/dmd.conf is not owned by any package [kai@worky ~]$ rpm -ql dmd | grep dmd.conf /usr/share/man/man5/dmd.conf.5.gz Thanks for the fast replies!
Re: datetime fails with undefined reference
Great news! Worked like a champ. Is there documentation somewhere that I missed? I would love to be able to answer these questions on my own. I've been stumped on this one for a week :(
datetime fails with undefined reference
I can't seem to use std.datetime at all. I get undefined reference on whether I use a StopWatch, or if I just try to compile the unittest. All I have to do is declare a StopWatch: import std.stdio; import std.datetime; void main() { StopWatch sw; } This fails to compile: [kai@worky ~]$ dmd datetime_test.d /usr/lib/gcc/x86_64-redhat-linux/4.5.1/../../../../lib/libphobos2.a(datetime_35c_30e.o): In function `_D3std8datetime7systimeFNeZS3std8datetime5Ticks': std/datetime.d:(.text._D3std8datetime7systimeFNeZS3std8datetime5Ticks+0x1c): undefined reference to `clock_gettime' /usr/lib/gcc/x86_64-redhat-linux/4.5.1/../../../../lib/libphobos2.a(datetime_359_1fe.o): In function `_D3std8datetime5Ticks12_staticCtor5OFNeZv': std/datetime.d:(.text._D3std8datetime5Ticks12_staticCtor5OFNeZv+0x1b): undefined reference to `clock_getres' collect2: ld returned 1 exit status --- errorlevel 1 Am I missing some libraries somewhere? If I 'import core.sys.posix.time, core.sys.posix.sys.time;', parts of dattime work, and others don't. A main with just: writef("%s %s\n", (is(typeof({auto fp = &clock_gettime; }; Prints "true true", but using them like this gives undefined again: timespec ts; writef("%d\n", clock_getres(CLOCK_REALTIME, &ts)); datetime_test.o: In function `_Dmain': datetime_test.d:(.text._Dmain+0x34): undefined reference to `clock_getres' collect2: ld returned 1 exit status --- errorlevel 1 I'm running Fedora 14 x86_64, dmd-2.051-0.i386, glibc-2.13-1.i686. Any ideas?