1. Bug with where()?

Hello Rob, hello all,

recently I wrote a program to patch a .mbx file (the outbox of my
e-mail program). I decided to open the .mbx file as text file for
update. The principle of the program is demonstrated by "pets.ex(w)"
and "pets.txt" below.

When the program is running, something strange happens. It says:
"replaced 'dog' 6 times with 'cat'", but 'dog' only existed 2 times in
"pets.txt". Furthermore, "pets.txt" grows, from originally 60 bytes to
more than 700 bytes.
After activating the command flush(f), the program works as expected,
but I think it also should work correctly without flush(f).

It looks like a bug concerning to where(), similar to what has already
been fixed (described in the most recent section of relnotes.htm).

Regards,
   Juergen



--======================================================================
file pets.ex or pets.exw
------------------------------------------------------------------------
include file.e

object line
atom file_pos
integer f, p, replaced

f = open("pets.txt", "u")
replaced = 0
while 1 do
   file_pos = where(f)
   line = gets(f)
   if atom(line) then exit end if

   printf(1, "%d, ", {file_pos})
   p = match("dog", line)
   if p then
      line[p..p+2] = "cat"
      if seek(f, file_pos) then
         puts(1, "Cannot set the file pointer")
         abort(1)
      end if
      puts(f, line)
      -- flush(f)       -- !!
      replaced += 1
   end if
end while
close(f)
printf(1, "%d\n\n", {file_pos})
printf(1, "replaced 'dog' %d times with 'cat'\n\n", {replaced})
puts(1, "Press Enter...")
p = getc(0)
--======================================================================


--======================================================================
file pets.txt
------------------------------------------------------------------------
Galahad (dog)
Garbo (fish)
Garfield (dog)
Geesha (bird)
--======================================================================

new topic     » topic index » view message » categorize

2. Re: Bug with where()?

Juergen writes:

> After activating the command flush(f), the program works as expected,
> but I think it also should work correctly without flush(f).

Thanks for your example.
I duplicated your results.
I think this is an example of what I say in the docs
for seek():

"After seeking and reading (writing) a series of bytes,
you may need to call seek() explicitly before you switch
to writing (reading) bytes, even though the file position
should already be what you want."

Explicit seeking, or flushing corrects these problems.

Your example ran the same (undesired) way with the DJGPP-built
interpreter as well. This seems to be a basic problem with C I/O.
It's not really under my control, except that I could do a forced,
hidden flush(), in some cases, causing a possibly severe loss of
performance.

One minor thing. I recommend that you use "ub", rather than "u",
although it doesn't seem to matter in your example...

"This function [seek()] is normally used with files opened in
binary mode. In text mode, DOS [and Windows]
converts CR LF to LF on input, and LF to CR LF on output,
which can cause great confusion when you are trying to count bytes."

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

3. Re: Bug with where()?

Rob <rds at RapidEuphoria.com> wrote:

> Juergen writes:

>> After activating the command flush(f), the program works as expected,
>> but I think it also should work correctly without flush(f).

> Thanks for your example.
> I duplicated your results.
> I think this is an example of what I say in the docs
> for seek():

> "After seeking and reading (writing) a series of bytes,
> you may need to call seek() explicitly before you switch
> to writing (reading) bytes, even though the file position
> should already be what you want."

Before writing the program, I read your documentation for seek(), but
now it seems to me, that I didn't understand it 100%. In my program, I
used seek() immediately before puts(), but nowhere else. This lead to
the known problems.
Now, having read your hints, I inserted another seek() statement
immediately before gets(), and now the program works correctly without
flushing.
Thanks! Obviously, it was not so easy for me to understand.  blink

> Explicit seeking, or flushing corrects these problems.

Do these problems only occur when where() is used?

> Your example ran the same (undesired) way with the DJGPP-built
> interpreter as well. This seems to be a basic problem with C I/O.
> It's not really under my control, except that I could do a forced,
> hidden flush(), in some cases, causing a possibly severe loss of
> performance.

I see.

> One minor thing. I recommend that you use "ub", rather than "u",
> although it doesn't seem to matter in your example...

> "This function [seek()] is normally used with files opened in
> binary mode. In text mode, DOS [and Windows]
> converts CR LF to LF on input, and LF to CR LF on output,
> which can cause great confusion when you are trying to count bytes."

I wanted to use gets(), because it's much easier for me, to think of a
file as a "list of lines", rather than a stream of bytes. And I
erroneously assumed, that gets() couldn't be used for files that are
opened in binary mode.

> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    http://www.RapidEuphoria.com

Thanks for your advice!

Regards,
   Juergen

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu