QB64Team / qb64

BASIC for the modern era.
https://www.qb64.org
Other
672 stars 96 forks source link

LOC for a file begins at 1 instead of 0 for a newly opened file #201

Closed adam4235 closed 3 years ago

adam4235 commented 3 years ago

QB64 info (please complete the following information):

I'm not sure if this is intentional, and perhaps code depending on this difference is considered undefined or incorrect (I would agree that it's not optimal), I'm just reporting it as a bug on the assumption that QBasic and QB64 should have the same behaviour.

To Reproduce Compile and run this program:

OPEN "TEST.RND" FOR RANDOM AS #1 LEN = 12
CLS
PRINT LOC(1)

where TEST.RND is a binary file containing any random data.

Expected behavior Should print 0.

FellippeHeitor commented 3 years ago

Thanks for reporting.

aouwt commented 3 years ago

i believe that file indices start at 1 (eg. GET #1, 1, a~%% gets the first byte of the file, GET #1, 2, a~%% gets second, etc.) and I believe that behavior may be the same as in QB, however i am not certain. Nonetheless, this is an odd quirk of LOC that i, and probably none of the devs, have noticed before.

Although i can't mess around with it right now, in a moment i'll try to figure out this and maybe make a PR by the end of this week.

Thanks for reporting!

RhoSigma-QB64 commented 3 years ago

According to the Wiki, LOC seems to be mainly intended for COM port channels rather than files. Using the SEEK would be my personal choice for regular disk based files and 1 is absolute correct for new opend files as per the GET/PUT behavior mentioned by the previous speaker.

However, can't say how it was in QBasic1.1, but wouldn't necessarily take its behavior AS IS. Just because it's legacy, it doesn't mean it was bug free by itself.

RhoSigma-QB64 commented 3 years ago

Hm, according to the QuickBASIC4.5 reference manual

Page 351

To receive input from the communications port, use the INPUT$ function. The LOC function returns the number of characters waiting to be read.

Page 496

The SEEK function tells you the byte position where the very next read or write operation begins. (If you are using binary I/O to access a file, the LOC and SEEK functions give similar results, but LOC returns the position of the last byte read or written, while SEEK returns the position of the next byte to be read or written.)

As nothing is read or written yet in a new opened file, LOC should indeed return 0 here, while SEEK must return 1 (same for GET/PUT position)

Page 499/500

The EOF, LOC, and LOF functions can be used with the COMn: serial device; however, the values these functions return have a different meaning than the values they return when used with data files.

The values returned by the EOF, LOC, and LOF functions when used with a communications device return information about the size of this buffer, as shown in the following list:

  • EOF = Whether or not any characters are waiting to be read from the input buffer
  • LOC = The number of characters waiting in the input buffer
  • LOF = The amount of space remaining (in bytes) in the output buffer

Conclusion: We need to fix LOC without messing up SEEK...