EOF Function
Syntax
Syntax: result = EOF(#n)
Source: pb_cg_emit_eof (pb_codegen.c:6160)
Description
Returns -1 (TRUE) if the file pointer for file number #n has reached or passed the end of the file. Returns 0 (FALSE) if there is still data to read. EOF is typically used as the condition in a WHILE NOT EOF(#n) loop to read through all lines or records in a file.
Internally, EOF works by querying the total file size via GetFileSize and comparing it against the current file pointer position obtained via SetFilePointer with FILE_CURRENT. If the current position is greater than or equal to the file size, EOF returns TRUE.
Parameters
| Parameter | Description |
n | The integer file number to check. The file must be open. |
Return Value
| Value | Meaning |
-1 (TRUE) | File pointer is at or beyond the end of the file. No more data to read. |
0 (FALSE) | File pointer is before the end of the file. Data is still available. |
Example
FUNCTION PBMAIN() AS LONG
LOCAL ln AS STRING
LOCAL count AS LONG
count = 0
OPEN "data.txt" FOR INPUT AS #1
' Read file line by line until EOF
WHILE NOT EOF(1)
INCR count
LINE INPUT #1, ln
PRINT count; ": "; ln
WEND
PRINT "Total lines: "; count
CLOSE #1
FUNCTION = 0
END FUNCTION
Binary Mode EOF Check
OPEN "data.bin" FOR BINARY AS #2
WHILE NOT EOF(2)
GET #2, , val ' read 4-byte LONG
PRINT val
WEND
CLOSE #2
Generated Assembly
WinAPI Implementation
; EOF(#n) implementation using GetFileSize and SetFilePointer
; Step 1: Get total file size
mov rcx, [rbp - handle_offset] ; file handle
xor rdx, rdx ; lpFileSizeHigh = NULL (32-bit size only)
call [__imp_GetFileSize] ; returns file size in EAX (0xFFFFFFFF on error)
cmp rax, -1 ; INVALID_FILE_SIZE
je __pb_eof_error ; handle error, assume TRUE
mov [rbp - file_size], rax ; save total file size
; Step 2: Get current file pointer position
mov rcx, [rbp - handle_offset] ; file handle
xor rdx, rdx ; lDistanceToMove = 0
xor r8, r8 ; lpDistanceToMoveHigh = NULL
mov r9, 1 ; FILE_CURRENT (move 0 bytes from current)
call [__imp_SetFilePointer] ; returns current position in EAX
mov [rbp - current_pos], rax ; save current position
; Step 3: Compare position against file size
mov rax, [rbp - current_pos]
cmp rax, [rbp - file_size]
jge __pb_eof_true ; position >= file size -> TRUE
xor rax, rax ; FALSE = 0
jmp __pb_eof_done
__pb_eof_true:
mov rax, -1 ; TRUE = -1
__pb_eof_done:
; result is in RAX
__pb_eof_error:
mov rax, -1 ; on error, assume EOF = TRUE
Simplified/Alternative Path
; Some implementations cache the file size after each read.
; In that case, EOF is simply:
mov rcx, [rbp - handle_offset]
xor rdx, rdx
call [__imp_GetFileSize] ; get total size
cmp [rbp - bytes_read_total], eax ; compare cumulative bytes read
jae __pb_eof_true ; if read >= total, EOF = TRUE
xor rax, rax ; FALSE
jmp __pb_eof_done
__pb_eof_true:
mov rax, -1 ; TRUE
__pb_eof_done:
Imported WinAPI Functions
| Function | DLL | Purpose |
GetFileSize | kernel32.dll | Retrieve the total size of the file in bytes |
SetFilePointer | kernel32.dll | Query current file pointer position with FILE_CURRENT (0 offset) |
Notes
- If the file number is not open, EOF behavior is undefined. Always OPEN before checking EOF.
- EOF is most useful with sequential INPUT files and BINARY/RANDOM files. It works with any file mode.
- After the last line/record is read, the file pointer may not immediately trigger EOF until the next read attempt. Use
WHILE NOT EOF(n) rather than checking after each read.