I'm using FPC 3.2.0, though I doubt anything changed in the most recent releases, though I'll try those if folks think it's worth doing so.

What I ran across yesterday while doing a search for other things was some posts about updating a single line in a file using free pascal.  The solutions mostly centered around using stream objects or the inifile objects in lazarus.

This reminded me that I used to do this exact thing under turbo pascal by using blockread/writes, and treating the text file as a binary one.  This allowed me to make changes without having to rewrite the whole file, something even inifile still does.

To make a long story short, I tried that technique in FPC, and was a bit surprised by the results.

What happens is this:

On tp, I could open a file with a blocksize of 1,

reset(file1,1);

which would allow me to move through the file, and blockread/blockwrite whe ever I so chose to do so.

The problem with FPC comes in when I try this using strings.

For some reason, FPC treats the binary mode of the file as a license to treat each item written to it as a binary blob as well, and this breaks tp functionality.

For example.

Let's say I have a 5 byte string:

st1 := '12345';

Now, if I blockwrite this to the file under tp:

blockwrite(f1,st1);

The 1 for blocksize wasn't necessary, because tp already knows the blocks are of size 1 due to the reset command.

Now, if you were to open that text file in an editor, you would see 12345 as the first five bytes of the file (assuming I'd not moved the file pointer elsewhere first).

Interestingly enough, with FPC, it actually writes 6 bites, (and the blockcount is necessary).

blockwrite(f1,st1,6);

The reason it needs the extra byte is because the byte 0 (the one that stores the size of the string) is also written to the file. TP did not behave this way, though I don't know about delphi, though I'd doubt it dit.

It is fixable, one can simply return to the initial write location and write a space character to remove the offending character.

However, this doesn't account for long strings (haven't tested to see what happens in that case)

or other structures that might have additional overhead.

I would expect FPC to write just the structure elements, not the housekeeping bytes that go along with them when doing a blockwrite.

Is this a bug, or is this a deliberate design decision, and if so, can we talk about changing it's behavior?


The other issue I encountered while performing this test is when converting between strings and numbers, FPC does not follow TP functionality either.  That one at least is documented, so I was able to see why it did things the way it did.  However, this too, I think should be changed to behave as tp did, in that it simply ignored nonnumeric characters in the string, instead of aborting processing.

At the very least, it should go ahead and convert the numbers it did get before encountering a nonnumeric value instead of aborting the whole conversion attempt.

This can be demonstrated by something like this:

st1 := '123';

val(st,number,code);

(this produces a value in number of 123 as it should).

But, when one does:

st1 := #49+#50+#51+#13;

then the same code:

val(st,number,code);

produces an error, and code has the value of 4, (the place in the string where the error occurred), but number has a value of 0.

In tp, number would still have a value of 123, because it would simply ignore the carriage return at the end of the string.

I'm sure this one is by design (at least the not ignoring other charaters part, probably not the skipping assigning a value entirely part), but it would be helpful if it were modified to simply ignore all nonnumeric characters in the conversion string, the way tp handled it.

Comments?

I've built in workarounds in my program to solve both of these issues, but it'd be nice if I didn't have to do that.


_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to