www.digitalmars.com         C & C++   DMDScript  

D - possible bug with remove?

reply Charles Hixson <charleshixsn earthlink.net> writes:
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
parent reply "Walter" <walter digitalmars.com> writes:
"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
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
Walter wrote:
 "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.
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".)
Nov 04 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Charles Hixson" <charleshixsn earthlink.net> wrote in message
news:bo8lh2$289a$1 digitaldaemon.com...
 Walter wrote:
 "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.
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".)
In your file replace.d, qualify remove with file.remove.
Nov 04 2003
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
Walter wrote:
 "Charles Hixson" <charleshixsn earthlink.net> wrote in message
 news:bo8lh2$289a$1 digitaldaemon.com...
 
Walter wrote:

"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.
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".)
In your file replace.d, qualify remove with file.remove.
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!)
Nov 04 2003
next sibling parent "Walter" <walter digitalmars.com> writes:
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...

Walter wrote:

"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.
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".)
In your file replace.d, qualify remove with file.remove.
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!)
---------------------------------------------------------------------------- ----
 // 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
prev sibling parent reply Adam Harper <a-news-d harper.nu> writes:
<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 ctestde
Will come out as (if replacing "test" with "TEST":
 TEST aTEST bTEST cTEST
This 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
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
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
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
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
parent reply Adam Harper <a-news-d harper.nu> writes:
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).  My
One 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
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
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).  My
One 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
parent Adam Harper <a-news-d harper.nu> writes:
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