Jump to page: 1 2
Thread overview
possible bug with remove?
Nov 02, 2003
Charles Hixson
Nov 04, 2003
Walter
Nov 04, 2003
Charles Hixson
Nov 04, 2003
Walter
Nov 04, 2003
Charles Hixson
Nov 05, 2003
Walter
Nov 05, 2003
Adam Harper
Nov 06, 2003
Charles Hixson
Nov 06, 2003
Charles Hixson
Nov 06, 2003
Adam Harper
Nov 06, 2003
Charles Hixson
Nov 07, 2003
Adam Harper
November 02, 2003
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?
November 04, 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.


November 04, 2003
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".)

November 04, 2003
"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.


November 04, 2003
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!)



November 05, 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...
> >
> >>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());
> }
>


November 05, 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 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" :-)


November 06, 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.
> 
> ----
November 06, 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.
>>
>> ----
November 06, 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).  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.
>>>
>>> ----

« First   ‹ Prev
1 2