Re: A little of coordination for Rosettacode
On Thursday, 16 January 2014 at 01:11:23 UTC, bearophile wrote: - To test the compiler betas to see if they have "regressions" if you try to use the new features. This sounds somewhat paradox to me. How can a new feature have a regression? A "regression" means it has worked before, but new feature did not exist before. Maybe the question is about "before"? In my understanding "before" is "latest release", whereas "current" is "beta release" or "git HEAD". Do you mean "before" as something like "commit deadbeef~4" whereas "current" is "commit deadbeef"? I see nothing wrong with using code from Rosettacode to try out new features. It is weird though, if people want to test an example, you have to tell them to compile dmd from git. In practice the difference between the uses is not that important I think, because the sheer number of code snippets and release frequency means that most examples can be compiled with the latest release no matter what bearophile does. ;) Btw are your scripts public, bearophile?
Re: Why is string.front dchar?
On Thursday, 16 January 2014 at 05:56:48 UTC, Jakob Ovrum wrote: On Tuesday, 14 January 2014 at 11:42:34 UTC, Maxim Fomin wrote: The root of the issue is that string literals containing characters which do not fit into signle byte are still converted to char[] array. This is strictly speaking not type safe because it allows to reinterpret 2 or 4 byte code unit as sequence of characters of 1 byte size. The string type is in some sense problematic in D. That's why the fact that .front returns dhcar is a way to correct the problem, it is not an attempt to introduce confusion. This assertion makes all the wrong assumptions. `char` is a UTF-8 code unit[1], and `string` is an array of immutable UTF-8 code units. The whole point of UTF-8 is the ability to encode code points that need multiple bytes (UTF-8 code units), so the string literal behaviour is perfectly regular. This is wrong. String in D is de facto (by implementation, spec may say whatever is convenient for advertising D) array of single bytes which can keep UTF-8 code units. No way string type in D is always a string in a sense of code points/characters. Sometimes it happens that string type behaves like 'string', but if you put UTF-16 or UTF-32 text it would remind you what string type really is. Operations on code units are rare, which is why the standard library instead treats strings as ranges of code points, for correctness by default. However, we must not prevent the user from being able to work on arrays of code units, as many string algorithms can be optimized by not doing full UTF decoding. The standard library does this on many occasions, and there are more to come. This is attempt to explain problematic design as a wise action. Note that the Unicode definition of an unqualified "character" is the translation of a code *point*, which is very different from a *glyph*, which is what people generally associate the word "character" with. Thus, `string` is not an array of characters (i.e. an array where each element is a character), but `dstring` can be said to be. [1] http://dlang.org/type By the way, the link you provide says char is unsigned 8 bit type which can keep value of UTF-8 code unit. UTF is irrelevant because the problem is in D implementation. See http://forum.dlang.org/thread/hoopiiobddbapybbw...@forum.dlang.org (in particular 2nd page). The root of the issue is that D does not provide 'utf' type which would handle correctly strings and characters irrespective of the format. But instead the language pretends that it supports such type by allowing to convert to single byte char array both literals "sad" and "säд". And ['s', 'ä', 'д'] is by the way neither char[], no wchar[], even not dchar[] but sequence of integers, which compounds oddities in character types. Problems with string type can be illustrated as possible situation in domain of integers type. Assume that user wants 'number' type which accepts both integers, floats and doubles and treats them properly. This would require either library solution or a new special type in a language which is supported by both compiler and runtime library, which performs operation at runtime on objects of number type according to their effective type. D designers want to support such feature (to make the language better), but as it happens in other situations, the support is only limited: compiler allows to do alias immutable(int)[] number; number my_number = [0, 3.14, 3.14l]; but there is no support in runtime library. On surface, this looks like language have type which supports wanted feature, but if you use it, you will face the problems, as my_number[2] would give strange integer instead of float 3.14 and length of this array is 4 instead of 3. In addition this is not a type safe approach because there is option to reinterpret double as two integers. Now in order to fix this, there is number of functions in library which treat number type properly. Such practice (limited and broken language support, unsafe and illogical type, functions to correct design mistakes) is embedded into practice so deeply, that anyone who point out on this problem in newsgroup is treated as a fool and is sent to study IEE 754 standard.
Re: Why is string.front dchar?
On Wednesday, 15 January 2014 at 20:05:32 UTC, TheFlyingFiddle wrote: This is why i was confused really since the normal foreach is char it's weird that string.front is not a char. But if foreach being a char is only the way it is for legacy reasons it all makes sense. Unfortunately, it's not that simple. D arrays/slices have two distinct interfaces - the slice interface and the range interface. The latter is a library convention built on top of the former - thus the existence of the slice interface is necessary. A generic algorithm can choose to work on arrays (array algorithm) or ranges (range algorithm) among other kinds of type federations: auto algo(E)(E[] t); // array algorithm auto algo(R)(R r) if (isInputRange!R); // range algorithm The array algorithm can assume that: foreach(e; t) static assert(is(typeof(e) == E)); While the range algorithm *cannot* assume that: foreach(e; r) static assert(is(typeof(e) == ElementType!R)); Because this fails when R is a narrow string (slice of UTF-8 or UTF-16 code units). Thus, the correct way to use foreach over a range in a generic range algorithm is: foreach(ElementType!R e; r) {} Swapping the default just swaps which kind of algorithm can make the assumption. The added cost of breaking existing algorithms is a big deal, but as demonstrated, it's not a panacea.
Re: Why is string.front dchar?
On Tuesday, 14 January 2014 at 11:42:34 UTC, Maxim Fomin wrote: The root of the issue is that string literals containing characters which do not fit into signle byte are still converted to char[] array. This is strictly speaking not type safe because it allows to reinterpret 2 or 4 byte code unit as sequence of characters of 1 byte size. The string type is in some sense problematic in D. That's why the fact that .front returns dhcar is a way to correct the problem, it is not an attempt to introduce confusion. This assertion makes all the wrong assumptions. `char` is a UTF-8 code unit[1], and `string` is an array of immutable UTF-8 code units. The whole point of UTF-8 is the ability to encode code points that need multiple bytes (UTF-8 code units), so the string literal behaviour is perfectly regular. Operations on code units are rare, which is why the standard library instead treats strings as ranges of code points, for correctness by default. However, we must not prevent the user from being able to work on arrays of code units, as many string algorithms can be optimized by not doing full UTF decoding. The standard library does this on many occasions, and there are more to come. Note that the Unicode definition of an unqualified "character" is the translation of a code *point*, which is very different from a *glyph*, which is what people generally associate the word "character" with. Thus, `string` is not an array of characters (i.e. an array where each element is a character), but `dstring` can be said to be. [1] http://dlang.org/type
Re: A little of coordination for Rosettacode
arithmetic_evaluation.d balanced_ternary.d combinations_with_repetitions1.d k_means_plus_plus_clustering.d names_to_numbers.d or number_names.d I have "fixed" them. This is the problem in array, already in Bugzilla, I think it's a kind of regression: import std.array: array; immutable foo = [""].array; void main() {} The problem with inout in balanced_ternary.d was caused by inout semantics that keeps subtly changing every month. I don't know the causes of such micro-regressions. Bye, bearophile
Re: A little of coordination for Rosettacode
qznc: [0] https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master [1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694 Few of the tasks of your list were never updated to D2/Phobos, and they should be updated. Among the ones that are updated, I have found five that don't compile on dmd 2.065 because of compiler changes and one (I think already reported) regression in std.array.array: arithmetic_evaluation.d balanced_ternary.d combinations_with_repetitions1.d k_means_plus_plus_clustering.d names_to_numbers.d or number_names.d I will try to fix them (and probably I will leave the one with a regression untouched). Bye, bearophile
Re: A little of coordination for Rosettacode
Brad Roberts: Requiring that users of the code in resottacode be using bleeding edge, unreleased, compilers is a disservice to those users. Typical users will not and should not need to use anything other than a released compiler. Some of the rosettacode usages/purposes are: - Trying new compiler features to see if they work correctly; - Try the new compiler features to learn to use them effectively; - To test the compiler betas to see if they have "regressions" if you try to use the new features. - To show "good" (== short, fast, elegant, clean) D code, thanks to some nicer recently introduced compiler improvements; So do you want to throw away those purposes? Also keep in mind that if you throw away those purposes, I will lose some of my desire to work on Rosettacode, so you will have a less good and less updated rosettacode site. And I have found probably more than 300 dmd bugs/regressions thanks to those beta-related purposes. If you throw away those purposes you will lose a significant amount of my future bug reports. Are those prices low enough for you? The point is you shouldn't have to, unless the code is taking advantage of broken behavior. Any changes that 'have' to be made due to a compiler release need to be carefully examined as probable regressions in the compiler. One of the points of improving a compiler is offering new features that are advantageous to use. If you don't want to use them it often means they are a failure. In many other cases the dmd compiler rejects older code that was wrong, because it becomes more tight. Rosettacode tasks are usually short. If you don't try new compiler features in such little programs that have no production-level significance, then you will never try them in production code, and you will probably use just C-like code. Being a little compiler-bold in those tasks is acceptable. Bye, bearophile
Re: A little of coordination for Rosettacode
On 1/15/14 4:42 PM, bearophile wrote: Brad Roberts: I think this is a mistake. They should compile with a released compiler. Why? And why do you think that outweighs the several advantages of having entries compilable only with the latest beta compiler? (Currently there are 40-50 entries that don't compile with the released dmd 2.064.) Requiring that users of the code in resottacode be using bleeding edge, unreleased, compilers is a disservice to those users. Typical users will not and should not need to use anything other than a released compiler. They also likely form a potentially interesting set of regression tests that someone ought to volunteer to test beta's against. Rosettacode site has many different purposes; I also use those programs to test the dmd compiler for regressions. But to do this effectively you have to use the latest compiler changes. Also, how can you update manually on the site tens of entries all at once when a new compiler comes out? The point is you shouldn't have to, unless the code is taking advantage of broken behavior. Any changes that 'have' to be made due to a compiler release need to be carefully examined as probable regressions in the compiler.
Re: A little of coordination for Rosettacode
Brad Roberts: I think this is a mistake. They should compile with a released compiler. Why? And why do you think that outweighs the several advantages of having entries compilable only with the latest beta compiler? (Currently there are 40-50 entries that don't compile with the released dmd 2.064.) They also likely form a potentially interesting set of regression tests that someone ought to volunteer to test beta's against. Rosettacode site has many different purposes; I also use those programs to test the dmd compiler for regressions. But to do this effectively you have to use the latest compiler changes. Also, how can you update manually on the site tens of entries all at once when a new compiler comes out? Bye, bearophile
Re: A little of coordination for Rosettacode
On 1/15/14 4:18 PM, bearophile wrote: What version of the D compiler are you using? I am assuming Rosettacode to be compilable with the latest "bleeding edge" compiler. So if you use the latest released compiler some of the entries will not compile. Such entries should not be "fixed" at all. I think this is a mistake. They should compile with a released compiler. They also likely form a potentially interesting set of regression tests that someone ought to volunteer to test beta's against.
Re: A little of coordination for Rosettacode
[0] https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master [1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694 Another reason for some of your entries to not compile seems to be that you have missed that some entries need other entries to compile, so "rc_24_game_solve.d" needs "permutations2.d" and "arithmetic_rational.d", and then compiles and runs fine. (I number 1 2 3 ... the tasks that have more than one D solution). Bye, bearophile
Re: A little of coordination for Rosettacode
https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master [1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694 Regarding Task names that start with a number, like rosettacode_24_game_solve_00.d, I usually prefix them with "rc_". Bye, bearophile
Re: A little of coordination for Rosettacode
qznc: I just made some scripts [0] to download and compile all D examples from Rosettacode. From 186 of 716 examples fail to compile [1]. Some for trivial reasons like not wrapped into a main function or a missing import. Some require SDL or Tango or other third-party libraries. My ultimate goal was to use this for regression testing dmd. Anyways if people try code examples they should compile out of the box for good PR. If you are looking for a low-barrier way to support D a little, feel free to check out the fail list [1] and fix some. :) [0] https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master [1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694 I am using similar scripts written in Python since years. Currently there are around 760-770 D programs in Rosettacode. What version of the D compiler are you using? I am assuming Rosettacode to be compilable with the latest "bleeding edge" compiler. So if you use the latest released compiler some of the entries will not compile. Such entries should not be "fixed" at all. Your list of failing to compile just say "fail", but there are several reasons for a program to fail. Some programs need a "modulename_main" version to be compiled, because D lacks a built-in way to tell apart the main module of a program from the other modules. (In Python you use the "if __name__ == '__main__':" for this purpose). Some programs don't compile because require Tango. I have not removed them all because some Tango programmer has written them and I guess such person doesn't like to see their work removed from the pages. Some entries don't compile because they are not yet updated, or dmd has had some regressions. Thankfully Kenji usually fixes such regressions in just few days when I find them. Bye, bearophile
Re: std.algorithm for changing array values
Kapps: One thing to keep in mind is that structs are passed by value, so this foreach would be operating on a copy of the entry. So your setting the value to 42 would have no effect. Instead you would need "foreach(ref entry; entries)" in order to have the change take effect (regardless of whether or not you use std.algorithm). This is a common bug in D code, especially in code of D newbies, but it's also occasionally present in the code of more seasoned D programmers. One solution to avoid it that I suggested is that on default foreach yields const values. So if you want to mutate the value you have to add a "mutable" or "ref": foreach (mutable entry; entries) { Another language solution is to iterate by reference on default, so the ref is implicit: foreach (entry; entries) { And if you want to iterate by value you need to write something different. There are other solutions. But none of them were accepted by Walter :-( Bye, bearophile
Re: Compile/link Win64
On 1/12/2014 5:37 PM, Erik van Velzen wrote: On Friday, 10 January 2014 at 21:47:23 UTC, Nick Sabalausky wrote: Hmm, I hadn't ever uninstalled it. Regardless, *now* I've just uninstalled and reinstalled the Windows SDK, and re-ran vcvarsall.bat. The %WindowsSdkDir% is now set, but I'm still getting the same problem. The %WindowsSdkDir% is set to "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A", but there doesn't appear to be much in there (Just a "Bootstrapper\Packages" directory with not much inside it either). I don't think it installed correctly. There doesn't appear to be any other Windows SDK installation AFAICT either. Stupid f#&*^ microsoft tools... The lastest Windows SDK installs to C:\Program Files (x86)\Windows Kits\8.1\ "\Program Files (x86)\Windows Kits\" doesn't exist :( As I suspected, it must not have installed correctly.
Re: Is continuously seeding a random number generator performance intensive?
On Friday, 3 January 2014 at 13:39:41 UTC, Andrea Fontana wrote: On Friday, 3 January 2014 at 01:01:21 UTC, Frustrated wrote: On Thursday, 2 January 2014 at 20:38:10 UTC, Jeroen Bollen wrote: [...] e.g., seed(k); for(i = 1..10) print(rnd(i)); and for(i = 1..10) { seed(time); print(rnd(i)); } will both produce random sequences of numbers(and random sequences of numbers are "identically random". [...] The second example is error-prone. If "time" var doesn't change between cycle, it's not random at all. Wrong, in this example I'm using rnd(i) as having a seed i. Obviously, I'm not using i as an interval. i still changes per iteration of the loop so rnd still changes. (if I did not seed the rnd I would not have used rnd(i) but rnd;) i.e., for(i = 1..10) { seed(time); print(rnd(i)); } and for(i = 1..10) { seed(time); print(rnd); } are different but my example could easily have been written as for(i = 1..10) { seed(time+i); print(rnd); } which may be more obvious. The point of writing it the first way was to try to make it more clear about actually changing the seed vs the ith random number. (the seed changes the sequence of random numbers to another sequence but rnd returns the ith value in the sequence which is ultimately cyclical)
Re: Is continuously seeding a random number generator performance intensive?
On Wednesday, 15 January 2014 at 21:00:57 UTC, Jeroen Bollen wrote: How do you correctly create a MersenneTwisterEngine with a ulong as seed? If you are trying to create a very large 2D noise generator, this is how you do it, and you can any degree of smoothness you want: Create a 2D RNG. e.g., RND2D(x,y) { seed(S + x + N*y); return rand; } You could use this to generate your whole map very predictably up to the seed length(at some point it will repeat because of the finite size of the seed). If you have any degree of smoothness you do not want to use this per point unless you do want to have some "noise" which could be controlled by weighting the RND2D function so intergrid points are not so random: RND2D(x,y, xS, yS) { s = RND2D(x,y) sm1m1 = RND2D((int)(x/xS) - 1, (int)(y / yS - 1)); sm1m1 = RND2D((int)(x/xS) - 1, (int)(y / yS + 1)); ... return interpolate(s, x, y, sm1m1, sm1p1, ...); } where interpolate returns the modified seed that is partially based on the seed at the point x,y and partially an interpolation value between the sub grid points. Anyways, now that you have your RND2D you don't ever have to pre-generate your noise. Obviously it is more computationally expensive though. I guess this was the function you were looking for before if I now understand what you are trying to do?
Re: std.algorithm for changing array values
On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote: Hi, I checked std.algorithm but have no glue which functions I can use to rewrite following code with some nice algorithm functions. I have an array of structs. I want to check for a specific key and if found I change the value. If it is not found I add the entry. Kind regards André struct Data{ int key; int value; } void main(){ Data[] entries = [Data(1,1),Data(2,2)]; bool found; foreach(entry;entries){ if (entry.key == 3){ entry.value = 42; found = true; } } if (found == false){ entries ~= Data(3,42); } } Ranges in general don't work very well for modifying values in place. The Data structs are passed by value between functions, so any modifications made won't be reflected in the original array. Using ranges to modify values usually entails making a copy. You can still use std.algorithm to simplify the above code a bit, however: void main() { auto entries = [Data(1, 1), Data(2, 2)]; auto pos = entries.countUntil!(d => d.key == 3); if (pos >= 0) { entries[pos].value = 42; } else { entries ~= Data(3, 42); } writeln(entries); } Basically, just to abstract away the loop.
Re: std.algorithm for changing array values
On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote: foreach(entry;entries){ if (entry.key == 3){ entry.value = 42; found = true; } } One thing to keep in mind is that structs are passed by value, so this foreach would be operating on a copy of the entry. So your setting the value to 42 would have no effect. Instead you would need "foreach(ref entry; entries)" in order to have the change take effect (regardless of whether or not you use std.algorithm).
Re: Is continuously seeding a random number generator performance intensive?
How do you correctly create a MersenneTwisterEngine with a ulong as seed?
Re: std.algorithm for changing array values
Am 15.01.2014 21:54, schrieb anonymous: If you want to stop after the first match: auto f = entries.find!(d => d.key == 3); if(f.empty) entries ~= Data(3,42); else f.front.value = 42; If there can be duplicates and you want to change them all: auto f = entries.filter!(d => d.key == 3); if(f.empty) entries ~= Data(3,42); else foreach(ref e; f) e.value = 42; Fantastic! Thanks a lot. Kind regards André
Re: std.algorithm for changing array values
On Wednesday, 15 January 2014 at 20:54:06 UTC, anonymous wrote: On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote: Hi, I checked std.algorithm but have no glue which functions I can use to rewrite following code with some nice algorithm functions. I have an array of structs. I want to check for a specific key and if found I change the value. If it is not found I add the entry. Kind regards André struct Data{ int key; int value; } void main(){ Data[] entries = [Data(1,1),Data(2,2)]; [...] If you want to stop after the first match: auto f = entries.find!(d => d.key == 3); if(f.empty) entries ~= Data(3,42); else f.front.value = 42; If there can be duplicates and you want to change them all: auto f = entries.filter!(d => d.key == 3); if(f.empty) entries ~= Data(3,42); else foreach(ref e; f) e.value = 42; PS: You might want to consider using a different data structure with better performance. An associative array for example: int[int] entries = [1: 1, 2: 2]; entries[3] = 42;
Re: std.algorithm for changing array values
On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote: Hi, I checked std.algorithm but have no glue which functions I can use to rewrite following code with some nice algorithm functions. I have an array of structs. I want to check for a specific key and if found I change the value. If it is not found I add the entry. Kind regards André struct Data{ int key; int value; } void main(){ Data[] entries = [Data(1,1),Data(2,2)]; bool found; foreach(entry;entries){ if (entry.key == 3){ entry.value = 42; found = true; } } if (found == false){ entries ~= Data(3,42); } } If you want to stop after the first match: auto f = entries.find!(d => d.key == 3); if(f.empty) entries ~= Data(3,42); else f.front.value = 42; If there can be duplicates and you want to change them all: auto f = entries.filter!(d => d.key == 3); if(f.empty) entries ~= Data(3,42); else foreach(ref e; f) e.value = 42;
Re: std.algorithm for changing array values
On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote: Hi, I checked std.algorithm but have no glue which functions I can use to rewrite following code with some nice algorithm functions. I have an array of structs. I want to check for a specific key and if found I change the value. If it is not found I add the entry. Kind regards André struct Data{ int key; int value; } void main(){ Data[] entries = [Data(1,1),Data(2,2)]; bool found; foreach(entry;entries){ if (entry.key == 3){ entry.value = 42; found = true; } } if (found == false){ entries ~= Data(3,42); } } You can use canFind. import std.algorithm; struct Data{ int key; int value; } void main() { auto entries = [Data(1,1),Data(2,2)]; if(!entries.canFind!(x => x.key == 3)) entries ~= Data(3, 42); }
std.algorithm for changing array values
Hi, I checked std.algorithm but have no glue which functions I can use to rewrite following code with some nice algorithm functions. I have an array of structs. I want to check for a specific key and if found I change the value. If it is not found I add the entry. Kind regards André struct Data{ int key; int value; } void main(){ Data[] entries = [Data(1,1),Data(2,2)]; bool found; foreach(entry;entries){ if (entry.key == 3){ entry.value = 42; found = true; } } if (found == false){ entries ~= Data(3,42); } }
Re: Why is string.front dchar?
On Tuesday, 14 January 2014 at 01:12:40 UTC, bearophile wrote: TheFlyingFiddle: But for backwards compatibility reasons in this code: foreach (c; "somestring") c is a char, not a dchar. You have to type it explicitly to handle the UTF safely: foreach (dchar c; "somestring") This is why i was confused really since the normal foreach is char it's weird that string.front is not a char. But if foreach being a char is only the way it is for legacy reasons it all makes sense.
Re: A little of coordination for Rosettacode
I just made some scripts [0] to download and compile all D examples from Rosettacode. From 186 of 716 examples fail to compile [1]. Some for trivial reasons like not wrapped into a main function or a missing import. Some require SDL or Tango or other third-party libraries. My ultimate goal was to use this for regression testing dmd. Anyways if people try code examples they should compile out of the box for good PR. If you are looking for a low-barrier way to support D a little, feel free to check out the fail list [1] and fix some. :) [0] https://bitbucket.org/qznc/rosetta/src/da12e3673b0d/compile_all/?at=master [1] https://gist.github.com/qznc/9ba4b0e78abfc35d4694
Re: errors with filesystem operations
On Wed, 15 Jan 2014 13:41:50 +0100, Jacob Carlborg wrote: ... On Linux, hidden files are all files where the filename starts with a dot. To make it visible you need to rename the file. As far as I know, Linux doesn't have any form of system attribute. I am aware of this. However, FAT32 and NTFS (through ntfs-3g) and even ExFAT (I do not remember now the name of the project) are supported by Linux, so there should be a way to alter file structure so as to change attributes even if the OS does not natively provide a function for this (why should a user working in Linux be forced to reboot in Windows not even to run an unported application but just to change file attributes in a filesystem the OS supports)? Has anyone attempted it from D?
Re: errors with filesystem operations
On 2014-01-15 11:33, Hugo Florentino wrote: Hi, I am trying to make a little application to revert the effect of some viruses on USB memories, and running it from Windows encountered some exceptions that IMHO should not have happened. Maybe I am missing something. Can you please check the commented blocks for errors? Also, is there a way from Linux to remove attributes readonly, system, hidden ? As of 2.065 (not release yet) you can set file attributes using std.file.setAttributes [1]. On Linux, hidden files are all files where the filename starts with a dot. To make it visible you need to rename the file. As far as I know, Linux doesn't have any form of system attribute. [1] https://github.com/D-Programming-Language/phobos/commit/5ab8dae665c27ed45eced244720e23e53ef23457 -- /Jacob Carlborg
errors with filesystem operations
Hi, I am trying to make a little application to revert the effect of some viruses on USB memories, and running it from Windows encountered some exceptions that IMHO should not have happened. Maybe I am missing something. Can you please check the commented blocks for errors? Also, is there a way from Linux to remove attributes readonly, system, hidden ? Regards, Hugo import std.stdio; import std.path; import std.regex; import std.file; import std.string; static string info = "CureUSB 0.3 (2014-01-14)"; static string str_moved = "Moved"; static string str_deleted = "Deleted"; static string str_finished = "Done"; static string str_setattrib = "Attributes set"; static string str_safename = "SafeToDelete"; // Expression to match directories with blanks for name static auto re = regex(`^\s+$`); version(Windows) { import core.sys.windows.windows; extern(Windows) uint SetFileAttributesA(LPCSTR, DWORD); } int main() { string ExePath = thisExePath(); string SearchPath = rootName(ExePath); string BlankDirToDelete; version(Windows) SetConsoleOutputCP(65001); writefln(info); foreach(DirEntry d; dirEntries(SearchPath, SpanMode.shallow)) { auto m = matchFirst(baseName(d.name), re); if (m.captures.length > 0) { if (isDir(d.name)) { foreach(DirEntry f; dirEntries(d.name, SpanMode.shallow)) { string origname = buildPath(SearchPath, baseName(f.name)); rename(f.name, origname); writefln(`%s "%s"`, str_moved, origname); } BlankDirToDelete = d.name; } break; } } // The following block does not work; supposedly the process does not have // access to the directory because it is being used by another process, // which does not seem to be the case. Uncomment to try /* if (exists(BlankDirToDelete)) try { string SafeToBeDeleted = buildPath(SearchPath, str_safename) rename(BlankDirToDelete, SafeToBeDeleted); remove(SafeToBeDeleted); } catch (FileException e) writeln(e.msg); */ foreach(DirEntry d; dirEntries(SearchPath, SpanMode.shallow)) { if (d.name != ExePath) { string bname = baseName(d.name); version(Windows) { if ( (bname != "RECYCLER") && (bname != "$Recycle.bin") && (bname != "System Volume Information") && (bname != "Recovery") && (bname != "MSOCache") ) SetFileAttributesA(toStringz(d.name), FILE_ATTRIBUTE_NORMAL + FILE_ATTRIBUTE_ARCHIVE); } // The following block gives a FileException, claiming that the specified file // could not befound. Uncomment to try /* string exten = extension(d.name); if (exten.length > 0) { // writefln(`"%s" "%s"`, d.name, extension(d.name)); //debug line if ( (exten == ".exe") || (exten == ".lnk") || (exten == ".scr") || (exten == ".cpl") || (exten == ".hta") || (exten == ".com") || (exten == ".bat") || (exten == ".vb") || (exten == ".vbs") ) if (isDir(buildPath(SearchPath, stripExtension(baseName(d.name) { remove(d.name); writefln(`%s "%s"`, str_deleted, d.name); } } */ } } writefln("%s", str_setattrib); writefln("%s.", str_finished); return 0; }