D - possible bug with remove?
- Charles Hixson (19/19) Nov 02 2003 while trying to convert replace.c into replace.d I began getting the
- Walter (4/13) Nov 03 2003 Try qualifying the call to file.remove, as what's happening here is two
- Charles Hixson (8/27) Nov 04 2003 Well, I mean the one at line 365 of file.d, not the one at line 172,
- Walter (3/30) Nov 04 2003 In your file replace.d, qualify remove with file.remove.
- Charles Hixson (17/55) Nov 04 2003 It is qualified that way...but that turns out to not really be the
- Walter (6/190) Nov 04 2003 Try cutting down your example to a smaller one. That usually reveals jus...
-
Adam Harper
(67/128)
Nov 05 2003
- Charles Hixson (24/33) Nov 05 2003 That's a better critique than I could have hoped for. (Some of the
- Charles Hixson (10/49) Nov 05 2003 Nope. The std was just you having a different library structure
- Adam Harper (15/66) Nov 06 2003 One of the files I attached (replace-0.75.d) is using the new (as of dmd
- Charles Hixson (10/98) Nov 06 2003 Hmnh...
- Adam Harper (169/194) Nov 07 2003 Hmm... I don't really know what was going wrong for you originally, I
while trying to convert replace.c into replace.d I began getting the message: charles Mandala:~/Projects/sqlite/d/src$ dmd replace.d /usr/local/dmd/src/phobos/file.d(365): function remove conflicts with stdio.remove at /usr/local/dmd/src/phobos/c/stdio.d(179) the causative statement appears to be: file.remove (backupname); /* Delete any existing backup. */ And other similar statements, but the compiler only reports one at a time. Possibly I'm supposed to use some other technique to delete/unlink an existing file, but I don't know what it should be. I've tried several variations on the statement, and gotten different error messages with some of them. (Some made sense, others didn't...but as I'm still a novice I don't find that surprising.) So I have two questions: 1) How should I be deleting the file? and 2) Is this a bug, or am I just attempting to misuse an internal procedure that isn't intended to be used outside the library?
Nov 02 2003
"Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo3hf7$127u$1 digitaldaemon.com...while trying to convert replace.c into replace.d I began getting the message: charles Mandala:~/Projects/sqlite/d/src$ dmd replace.d /usr/local/dmd/src/phobos/file.d(365): function remove conflicts with stdio.remove at /usr/local/dmd/src/phobos/c/stdio.d(179) the causative statement appears to be: file.remove (backupname); /* Delete any existing backup. */ And other similar statements, but the compiler only reports one at a time.Try qualifying the call to file.remove, as what's happening here is two remove functions are being found.
Nov 03 2003
Walter wrote:"Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo3hf7$127u$1 digitaldaemon.com...Well, I mean the one at line 365 of file.d, not the one at line 172, and I'm on linux, so I assume that that version number is active, and since I don't know what DeleteFileA does, I assume that I want the version at line 365 (which isn't too long to copy into "my" program). But I don't know how to qualify to decide between them, and I doubt that copying libray code into my program is good style. (OTOH, I had been considering doing just that as a "quick fix".)while trying to convert replace.c into replace.d I began getting the message: charles Mandala:~/Projects/sqlite/d/src$ dmd replace.d /usr/local/dmd/src/phobos/file.d(365): function remove conflicts with stdio.remove at /usr/local/dmd/src/phobos/c/stdio.d(179) the causative statement appears to be: file.remove (backupname); /* Delete any existing backup. */ And other similar statements, but the compiler only reports one at a time.Try qualifying the call to file.remove, as what's happening here is two remove functions are being found.
Nov 04 2003
"Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo8lh2$289a$1 digitaldaemon.com...Walter wrote:In your file replace.d, qualify remove with file.remove."Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo3hf7$127u$1 digitaldaemon.com...Well, I mean the one at line 365 of file.d, not the one at line 172, and I'm on linux, so I assume that that version number is active, and since I don't know what DeleteFileA does, I assume that I want the version at line 365 (which isn't too long to copy into "my" program). But I don't know how to qualify to decide between them, and I doubt that copying libray code into my program is good style. (OTOH, I had been considering doing just that as a "quick fix".)while trying to convert replace.c into replace.d I began getting the message: charles Mandala:~/Projects/sqlite/d/src$ dmd replace.d /usr/local/dmd/src/phobos/file.d(365): function remove conflicts with stdio.remove at /usr/local/dmd/src/phobos/c/stdio.d(179) the causative statement appears to be: file.remove (backupname); /* Delete any existing backup. */ And other similar statements, but the compiler only reports one at a time.Try qualifying the call to file.remove, as what's happening here is two remove functions are being found.
Nov 04 2003
Walter wrote:"Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo8lh2$289a$1 digitaldaemon.com...It is qualified that way...but that turns out to not really be the trouble... I was importing three modules: //import file; import stream; //import c.stdio; It appears that I can't import both stream and c.stdio... so I commented out the c.stdio, and then it compiled, though printf wouldn't print anything to stdout, e.g.: c.stdio.printf ("start\n"); and oldstr = stream.stdin.readLine(); appeared to get caught in an endless loop. Ctrl-c would exit it, but enter wouldn't. And I expect that it will turn out that I need to import file. (Attached see proof that I don't know what I'm doing. And I thought that was such a simple exercise!)Walter wrote:In your file replace.d, qualify remove with file.remove."Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo3hf7$127u$1 digitaldaemon.com...Well, I mean the one at line 365 of file.d, not the one at line 172, and I'm on linux, so I assume that that version number is active, and since I don't know what DeleteFileA does, I assume that I want the version at line 365 (which isn't too long to copy into "my" program). But I don't know how to qualify to decide between them, and I doubt that copying libray code into my program is good style. (OTOH, I had been considering doing just that as a "quick fix".)while trying to convert replace.c into replace.d I began getting the message: charles Mandala:~/Projects/sqlite/d/src$ dmd replace.d /usr/local/dmd/src/phobos/file.d(365): function remove conflicts with stdio.remove at /usr/local/dmd/src/phobos/c/stdio.d(179) the causative statement appears to be: file.remove (backupname); /* Delete any existing backup. */ And other similar statements, but the compiler only reports one at a time.Try qualifying the call to file.remove, as what's happening here is two remove functions are being found.
Nov 04 2003
Try cutting down your example to a smaller one. That usually reveals just what is going wrong. "Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo92mt$2sdl$1 digitaldaemon.com...Walter wrote:---------------------------------------------------------------------------- ----"Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo8lh2$289a$1 digitaldaemon.com...It is qualified that way...but that turns out to not really be the trouble... I was importing three modules: //import file; import stream; //import c.stdio; It appears that I can't import both stream and c.stdio... so I commented out the c.stdio, and then it compiled, though printf wouldn't print anything to stdout, e.g.: c.stdio.printf ("start\n"); and oldstr = stream.stdin.readLine(); appeared to get caught in an endless loop. Ctrl-c would exit it, but enter wouldn't. And I expect that it will turn out that I need to import file. (Attached see proof that I don't know what I'm doing. And I thought that was such a simple exercise!)Walter wrote:In your file replace.d, qualify remove with file.remove."Charles Hixson" <charleshixsn earthlink.net> wrote in message news:bo3hf7$127u$1 digitaldaemon.com...Well, I mean the one at line 365 of file.d, not the one at line 172, and I'm on linux, so I assume that that version number is active, and since I don't know what DeleteFileA does, I assume that I want the version at line 365 (which isn't too long to copy into "my" program). But I don't know how to qualify to decide between them, and I doubt that copying libray code into my program is good style. (OTOH, I had been considering doing just that as a "quick fix".)while trying to convert replace.c into replace.d I began getting the message: charles Mandala:~/Projects/sqlite/d/src$ dmd replace.d /usr/local/dmd/src/phobos/file.d(365): function remove conflicts with stdio.remove at /usr/local/dmd/src/phobos/c/stdio.d(179) the causative statement appears to be: file.remove (backupname); /* Delete any existing backup. */ And other similar statements, but the compiler only reports one at a time.Try qualifying the call to file.remove, as what's happening here is two remove functions are being found.// replace.d 2003-11-01 Modified by: Charles Hixson /*_ replace.c Mon Nov 21 1988 Modified by: Walter Bright */ //import file; //import stream; //import c.stdio; // the replacing string and the string being replaced char[] newstr, oldstr; // the input and output files file filIn, filOut; uint strcount; int main (char[][] args) { int i; uint len; char[] sourcename, backupname; c.stdio.printf ("start\n"); if (args.length < 2) { c.stdio.printf ("Usage:\n\treplace filename(s)\n"); return (1); } c.stdio.printf ("String to be replaced? (terminate with a CR)\n"); oldstr = stream.stdin.readLine(); i = printf ("Replacement string? (terminate with a CR)\n"); newstr = stream.stdin.readLine(); strcount = 0; for (i = 1; i < args.length; i++) { char[] tempname; sourcename = args[i]; printf ("File <<%.*s>>\n"); tempname = sourcename ~ ".tmp"; backupname = sourcename ~ ".bak"; try { filOut = new File (tempname, FileMode.Out); } catch { printf ("cannot create/write to <<%.*s>>\n", tempname); continue; } try { filIn = new File(sourcename, FileMode.In); } catch { printf ("cannot open <<%.*s>> for reading\n", sourcename); } printf ("%.*s\n", backupname); continue; strcount = doReplace(); if (strcount > 0) { try { file_remove_365 (backupname); /* Delete any existing backup. */ file.rename (sourcename, backupname); file.rename (tempname, sourcename); } catch { printf ("File rename error with file <<%.*s>>\n", sourcename); // I think that in this case an abort is the correct answer // as some manual recovery work may need to be done char[] tmp = "File rename error with file <<"; tmp ~= sourcename ~ ">>"; throw ((new FileError(tmp))); } } else { printf ("No changes\n"); try { remove (tempname); } catch { printf ("could not delete file <<" ~ tempname ~ ">>\nmanual cleanup needed!\n"); } } backupname = ""; tempname = ""; printf ("%d strings replaced\n in <<%.*s>>", strcount, sourcename); strcount = 0; } } // the parameters are the global values: // filIn : the file of original data // filOut: the temporary data file // oldstr: the data to be replaced // newstr: the data replacing the old data // N.B.: String data values must be contained within one line // of the data file // N.B.: This implementation decides to conserve memory at a cost // in execution time (unless readLine and writeLine have a buffered // implementation). uint doReplace() { uint cnt = 0; char[] wrk1, wrk2; wrk1 = filIn.readLine(); while (! filIn.eof()) { cnt += replaceInLine(wrk1, oldstr, newstr, wrk2); filOut.writeLine(wrk2); } return cnt; } /******************************************** * Replace occurrences of from[] with to[] in s[]. * Closely based on the routine from phobos/string.d * inpLine is the data string for replacements (input line) * old is the pattern to be matched * to is the pattern that old is to be changed to * outLine is the revised data string (output line) * returned value is the count of replacements */ uint replaceInLine(char[] inpLine, char[] old, char[] to, char[] outLine) { char[] p; // the revised line int cnt = 0; // the count of replacements int i = 0; int istart = 0; // where the match starts int iend = inpLine.length - old.length + 1; // the last place to check if (old.length < 1) return 0; while (istart < iend) { i = find(inpLine[istart .. inpLine.length], old); if (i == -1) { p ~= inpLine[istart .. inpLine.length]; break; } p ~= inpLine[istart .. istart + i]; p ~= to; istart += i + old.length; cnt++; } outLine = p; return cnt; } /** the following routine is from phobos/file.d line 361-370 /*************************************************** * Delete a file. */ void file_remove_365(char[] name) { if (c.stdio.remove(toStringz(name)) == -1) throw new FileError(name, getErrno()); }
Nov 04 2003
<snip> Hi Charles, Walter (and anyone else who may be reading this thread), I've taken the liberty of going over the "replace.d" supplied by Charles, below are the changes needed to get it to compile. Apologies in advance if it comes across as overly critical. ---- You can, and should import file, stream and c.stdio Line 12:file filIn, filOut;Should be:File filIn, filOut;(This may, but probably not, have had something to do with the name conflicts). Line 26:i = printf ("Replacement string? (terminate with a CR)\n");You don't need "i = " in front of the printf. Line 34:printf ("File <<%.*s>>\n");Should be:printf ("File <<%.*s>>\n", sourcename);Lines 37 to 42:try { filOut = new File (tempname, FileMode.Out); } catch { printf ("cannot create/write to <<%.*s>>\n", tempname); continue; }Because the current file class doesn't actually create a file if it doesn't exist (see news://news.digitalmars.com:119/bng5g5$dc4$1 digitaldaemon.com for info), you need to explicitly create the file. This is a Windows only bug, the fix is to do the following instead:try { filOut = new File(); filOut.create( tempname, FileMode.Out ); } catch( FileError fe ) { c.stdio.printf( "cannot create/write to <<%.*s>>\n", tempname ); return 2; };You also probably don't want to continue after failing to open the file you plan to write the results into (in this case I've just replaced the continue with a return). Line 46 to 47:continue; strcount = doReplace();You don't need (or want) that continue there, otherwise "doReplace()" will never be called! You also need to add:filOut.close(); filIn.close();After the call to "doReplace()", otherwise subsequent operations on those files (like remove and rename) will fail. Line 50:file_remove_365 (backupname);Should be:file.remove (backupname);You'll also probably want to move that statement into it's own try/ catch loop, rather than grouping it with the renames. As a result lines 49 to 61 become:{ try { file.remove (backupname); // Delete any existing backup. } catch { // Don't need to worry about this }; try { file.rename (sourcename, backupname); file.rename (tempname, sourcename); } catch { printf ("File rename error with file <<%.*s>>\n", sourcename); // I think that in this case an abort is the correct answer // as some manual recovery work may need to be done char[] tmp = "File rename error with file <<"; tmp ~= sourcename ~ ">>"; throw ((new FileError(tmp))); }Currently "main" doesn't seem to return an int after successfully completing the for loop, so you'll want to add "return 0;" after that. Line 91:wrk1 = filIn.readLine();Should be moved within the while loop at line 92, otherwise it'll only ever perform replacements on the first line. As a result lines 91 to 95 become:while (! filIn.eof()) { wrk1 = filIn.readLine(); cnt += replaceInLine(wrk1, oldstr, newstr, wrk2); filOut.writeLine(wrk2); }Line 109:uint replaceInLine(char[] inpLine, char[] old, char[] to, char[] outLine)"outLine" should be an out parameter:uint replaceInLine(char[] inpLine, char[] old, char[] to, out char[] outLine)Line 114:int iend = inpLine.length - old.length + 1;Isn't needed (explanation coming up). Line 116:while (istart < iend)Should be:while (istart < inpLine.length)The reason you want to continue until the end of the input, rather than stopping after you've reached the last possible position a match can be found at is that lines like:test atest btest ctestdeWill come out as (if replacing "test" with "TEST":TEST aTEST bTEST cTESTThis is due to the while loop exiting before it fails to find a match (line 117) and tacks on the remainder of the line (line 119). Line 131 to 140: You can delete these as they are no longer needed. The only other issue that I can see is that trying to replace text in multiple files be specifying a wildcard (i.e. "replace *.txt") will fail because Windows doesn't expand the wildcard before starting the program and passing it the arguments (like most *nix shells do). So the program will try to perform a replacement on the file "*.txt", instead of all ".txt" files. But I think I'll leave that up to someone else to fix ;-) I've attached a copy of "replace.d", although along with the above changes I've also reformatted it to suit my tastes, sorry. Also attached is "replace-0.75.d" which is the same but using the new (as of dmd 0.75) standard library names. It was of course produced be running the previously compiled (with dmd 0.73) "replace.d" :-)
Nov 05 2003
That's a better critique than I could have hoped for. (Some of the errors you corrected are due to my going into a "try anything to just get SOMETHING working" after the original printf didn't work [and originally it didn't ask for a return value...so I looked through phobos trying for inspiration, and found a place where it specified printf with an integer return, so I tried that ..and that's why you only find that in a couple of places.) OTOH...I did get it to compile with several of the options (possibly not the final one). I just couldn't get it to print out anything, or appearantly to get past the first readLine. OTOH, it did echo back everything I typed whenever I hit a carriage return, so it wasn't hung. However, I notice that you changed the names of the files being imported. That's probably the key right there. I had said: //import file; import stream; //import c.stdio; (with various choices of commenting out) while you said: import std.file; import std.stream; import std.c.stdio; That's probably the answer that blocked me so that every approach I tried failed. Now, at least I should get far enough to get errors. Adam Harper wrote:<snip> Hi Charles, Walter (and anyone else who may be reading this thread), I've taken the liberty of going over the "replace.d" supplied by Charles, below are the changes needed to get it to compile. Apologies in advance if it comes across as overly critical. ----
Nov 05 2003
Nope. The std was just you having a different library structure than I do (you probably reconfigured it to match the recent discussions). My current guess is that it's the way you prefixed c.stdio. to all of the printf's etc. (I had been assuming that they were being recognized properly as no error messages were being thrown.) Anyway, I'm now starting to see messages, so I can *try* to figure out what's happening. Yeah!! (So far it's said "Usage:\n\treplace filename(s)\n", but that's what it *should* have said.) Charles Hixson wrote:That's a better critique than I could have hoped for. (Some of the errors you corrected are due to my going into a "try anything to just get SOMETHING working" after the original printf didn't work [and originally it didn't ask for a return value...so I looked through phobos trying for inspiration, and found a place where it specified printf with an integer return, so I tried that ..and that's why you only find that in a couple of places.) OTOH...I did get it to compile with several of the options (possibly not the final one). I just couldn't get it to print out anything, or appearantly to get past the first readLine. OTOH, it did echo back everything I typed whenever I hit a carriage return, so it wasn't hung. However, I notice that you changed the names of the files being imported. That's probably the key right there. I had said: //import file; import stream; //import c.stdio; (with various choices of commenting out) while you said: import std.file; import std.stream; import std.c.stdio; That's probably the answer that blocked me so that every approach I tried failed. Now, at least I should get far enough to get errors. Adam Harper wrote:<snip> Hi Charles, Walter (and anyone else who may be reading this thread), I've taken the liberty of going over the "replace.d" supplied by Charles, below are the changes needed to get it to compile. Apologies in advance if it comes across as overly critical. ----
Nov 05 2003
On Wed, 05 Nov 2003 17:21:55 -0800, Charles Hixson wrote:Nope. The std was just you having a different library structure than I do (you probably reconfigured it to match the recent discussions). MyOne of the files I attached (replace-0.75.d) is using the new (as of dmd 0.75) phobos/standard library layout, which has the "std." prefix. The other file I attached should work on all dmd's prior to 0.75.current guess is that it's the way you prefixed c.stdio. to all of the printf's etc. (I had been assuming that they were being recognized properly as no error messages were being thrown.) Anyway, I'm now starting to see messages, so I can *try* to figure out what's happening. Yeah!!Actually, the "c.stdio" prefix is completely superfluous, you can delete it without any ramifications. You can also remove the "import c.stdio;" line, it won't effect anything.(So far it's said "Usage:\n\treplace filename(s)\n", but that's what it *should* have said.)Having just tried the file I posted on Linux, I noticed that it was missing a "\n" at the end of the printf on line 112. That line should read:c.stdio.printf( "%d strings replaced in <<%.*s>>\n", strcount, sourcename );This was preventing it from outputting the "xx strings replaced in <<file>>" line(s). I could have sworn they were there on Windows. With the one change above the "replace.d" from my last message is compiling and working just fine in Linux. What's happening when you compile/run it?Charles Hixson wrote:That's a better critique than I could have hoped for. (Some of the errors you corrected are due to my going into a "try anything to just get SOMETHING working" after the original printf didn't work [and originally it didn't ask for a return value...so I looked through phobos trying for inspiration, and found a place where it specified printf with an integer return, so I tried that ..and that's why you only find that in a couple of places.) OTOH...I did get it to compile with several of the options (possibly not the final one). I just couldn't get it to print out anything, or appearantly to get past the first readLine. OTOH, it did echo back everything I typed whenever I hit a carriage return, so it wasn't hung. However, I notice that you changed the names of the files being imported. That's probably the key right there. I had said: //import file; import stream; //import c.stdio; (with various choices of commenting out) while you said: import std.file; import std.stream; import std.c.stdio; That's probably the answer that blocked me so that every approach I tried failed. Now, at least I should get far enough to get errors. Adam Harper wrote:<snip> Hi Charles, Walter (and anyone else who may be reading this thread), I've taken the liberty of going over the "replace.d" supplied by Charles, below are the changes needed to get it to compile. Apologies in advance if it comes across as overly critical. ----
Nov 06 2003
Hmnh... I wasn't even getting any output from the first printf statement. The one with a simple text string. So something else was wrong, but it isn't wrong now. Don't know what. (I tried it in several variations...the one assigning an integer parameter was merely the last effort.) Whatever, I'm past that now, and I've downloaded the new version of dmd, so I'll be putting the std's back on. But you have defused all of my possible guesses as to what was happening. Adam Harper wrote:On Wed, 05 Nov 2003 17:21:55 -0800, Charles Hixson wrote:Nope. The std was just you having a different library structure than I do (you probably reconfigured it to match the recent discussions). MyOne of the files I attached (replace-0.75.d) is using the new (as of dmd 0.75) phobos/standard library layout, which has the "std." prefix. The other file I attached should work on all dmd's prior to 0.75.current guess is that it's the way you prefixed c.stdio. to all of the printf's etc. (I had been assuming that they were being recognized properly as no error messages were being thrown.) Anyway, I'm now starting to see messages, so I can *try* to figure out what's happening. Yeah!!Actually, the "c.stdio" prefix is completely superfluous, you can delete it without any ramifications. You can also remove the "import c.stdio;" line, it won't effect anything.(So far it's said "Usage:\n\treplace filename(s)\n", but that's what it *should* have said.)Having just tried the file I posted on Linux, I noticed that it was missing a "\n" at the end of the printf on line 112. That line should read:c.stdio.printf( "%d strings replaced in <<%.*s>>\n", strcount, sourcename );This was preventing it from outputting the "xx strings replaced in <<file>>" line(s). I could have sworn they were there on Windows. With the one change above the "replace.d" from my last message is compiling and working just fine in Linux. What's happening when you compile/run it?Charles Hixson wrote:That's a better critique than I could have hoped for. (Some of the errors you corrected are due to my going into a "try anything to just get SOMETHING working" after the original printf didn't work [and originally it didn't ask for a return value...so I looked through phobos trying for inspiration, and found a place where it specified printf with an integer return, so I tried that ..and that's why you only find that in a couple of places.) OTOH...I did get it to compile with several of the options (possibly not the final one). I just couldn't get it to print out anything, or appearantly to get past the first readLine. OTOH, it did echo back everything I typed whenever I hit a carriage return, so it wasn't hung. However, I notice that you changed the names of the files being imported. That's probably the key right there. I had said: //import file; import stream; //import c.stdio; (with various choices of commenting out) while you said: import std.file; import std.stream; import std.c.stdio; That's probably the answer that blocked me so that every approach I tried failed. Now, at least I should get far enough to get errors. Adam Harper wrote:<snip> Hi Charles, Walter (and anyone else who may be reading this thread), I've taken the liberty of going over the "replace.d" supplied by Charles, below are the changes needed to get it to compile. Apologies in advance if it comes across as overly critical. ----
Nov 06 2003
On Thu, 06 Nov 2003 14:47:03 -0800, Charles Hixson wrote:Hmnh... I wasn't even getting any output from the first printf statement. The one with a simple text string. So something else was wrong, but it isn't wrong now. Don't know what. (I tried it in several variations...the one assigning an integer parameter was merely the last effort.)Hmm... I don't really know what was going wrong for you originally, I haven't even been able to reproduce your original error message using the file you posted on 04/11/2003. Below are the steps I went through to get that file compiling and working (to a degree) on my Linux box. First some basic info:aharper slinky:~$ uname -a aharper slinky:~$ gcc -v Reading specs from /usr/lib/gcc-lib/i486-linux/3.3.2/specs Configured with: ... Thread model: posix gcc version 3.3.2 (Debian) aharper slinky:~$ apps/devel/d/dmd/bin/dmd -v Digital Mars D Compiler Beta v0.69 Copyright (c) 1999-2003 by Digital Mars written by Walter Bright ...Now the changes I made line by line, in the order I made them. Line 12: Change 'file' to 'File' Still not compiling, error message is: > replace-ch.d(12): identifier 'file' is not defined Line 5: Uncomment 'import stream;' Now compiles. Prints: > aharper slinky:~/apps/devel/d$ ./replace-ch > start > Usage: > replace filename(s) When run. Attempting to use results in the following: > aharper slinky:~/apps/devel/d$ echo test atest btest ctestde > > test.txt > aharper slinky:~/apps/devel/d$ ./replace-ch test.txt > start > String to be replaced? (terminate with a CR) > test > Replacement string? (terminate with a CR) > TEST > Segmentation fault Line 34: Change to 'printf ("File <<%.*s>>\n", sourcename);' Running now results in: > aharper slinky:~/apps/devel/d$ ./replace-ch test.txt > start > String to be replaced? (terminate with a CR) > test > Replacement string? (terminate with a CR) > TEST > File <<test.txt>> > test.txt.bak > Error: Assertion Failure replace-ch.d(76) Line 18: Add a new line above with the text 'return 0;' Running now results in: > aharper slinky:~/apps/devel/d$ ./replace-ch test.txt > start > String to be replaced? (terminate with a CR) > test > Replacement string? (terminate with a CR) > TEST > File <<test.txt>> > test.txt.bak > aharper slinky:~/apps/devel/d$ cat test.txt > test atest btest ctestde > aharper slinky:~/apps/devel/d$ Line 46: Delete the line. Running now results in: > aharper slinky:~/apps/devel/d$ ./replace-ch test.txt > start > String to be replaced? (terminate with a CR) > test > Replacement string? (terminate with a CR) > TEST > File <<test.txt>> > test.txt.bak > No changes > 0 strings replaced > aharper slinky:~/apps/devel/d$ cat test.txt > test atest btest ctestde > aharper slinky:~/apps/devel/d$ Line 92: Move within while loop beginning on line 93. Running now results in: > aharper slinky:~/apps/devel/d$ ./replace-ch test.txt > start > String to be replaced? (terminate with a CR) > test > Replacement string? (terminate with a CR) > TEST > File <<test.txt>> > test.txt.bak > File rename error with file <<test.txt>> > Error: File rename error with file <<test.txt>>: file I/O Line 50: Move out of current try/catch loop and into separate try/catch loop above. Lines 49 to 58 should now look something like: > { try > { file_remove_365 (backupname); > } > catch > { > /* Ignore any errors */ > } > > try > { file.rename (sourcename, backupname); Running now results in: > aharper slinky:~/apps/devel/d$ ./replace-ch test.txt > start > String to be replaced? (terminate with a CR) > test > Replacement string? (terminate with a CR) > TEST > File <<test.txt>> > test.txt.bak > 4 strings replaced > aharper slinky:~/apps/devel/d$ cat test.txt > > aharper slinky:~/apps/devel/d$ Line 117: Make 'outLine' an out parameter: > uint replaceInLine(char[] inpLine, > char[] old, > char[] to, > out char[] outLine) Running now results in: > aharper slinky:~/apps/devel/d$ ./replace-ch test.txt > start > String to be replaced? (terminate with a CR) > test > Replacement string? (terminate with a CR) > TEST > File <<test.txt>> > test.txt.bak > 4 strings replaced > aharper slinky:~/apps/devel/d$ cat test.txt > TEST aTEST bTEST cTEST > aharper slinky:~/apps/devel/d$ Obviously there are still a few things that need doing, but the program compiles and runs without error. Now to try and reproduce your error... Starting with the file you originally posted again (discarding the changes made above) if we do the following: - Uncomment lines 5 and 6 (import stream and c.stdio) - Change 'file' on line 12 to 'File' Then when we compile we get (apologies for the wrapping):aharper slinky:~/apps/devel/d$ dmd/bin/dmd -c \ -I~/apps/devel/d/dmd/src/phobos replace-ch.d /home/aharper/apps/devel/d/dmd/src/phobos/file.d(367): function \ remove conflicts with stdio.remove at \ /home/aharper/apps/devel/d/dmd/src/phobos/c/stdio.d(179) aharper slinky:~/apps/devel/d$Which is your original error message! Re-commenting out line 6 (import c.stdio) results in a compile with no errors:aharper slinky:~/apps/devel/d$ dmd/bin/dmd -c \ -I~/apps/devel/d/dmd/src/phobos replace-ch.d aharper slinky:~/apps/devel/d$So there is a conflict between the 'c.stdio' import and the 'stream' import, or so it seems. The file I ended up with (after making the changes above, and then whatever other changes I mentioned in my first message) imports both and compiles and runs quite happily. So there isn't a conflict, or is but only in some particular circumstance. I don't particularly have the inclination to go any further in tracking this down, DMD 0.75 is out and with it a new library structure, one that for the most part uses private imports to avoid exactly this sort of thing. The one piece of advice I can give, having looked at this, is that import c.stdio isn't necessary, the compiler will import/link the symbols anyway (so, for example, printf works without having imported c.stdio). In fact it would seem that you should *avoid* explicitly importing c.stdio, otherwise you may get cryptic messages about conflicting functions from within the standard lib. At least that /was/ the situation with DMD's prior to 0.75, I don't know how things stand now. Anyway, I hope this has helped you Charles, and that you've now got at least a partial understanding of what was going on, me I am more confused than I was when I started :-) Also, the previous 'replace.d' I posted contains a few minor errors, like trying to catch the wrong sort of errors (FileError's instead of Open/WriteError's), so if you do anything with those keep that in mind.
Nov 07 2003