File I/O

Description

PowerBASIC file I/O uses numbered file handles (#n) and supports four access modes: sequential text (OUTPUT/APPEND/INPUT) and binary (BINARY). All operations ultimately map to the Windows API functions CreateFileA, ReadFile, WriteFile, SetFilePointer, and CloseHandle.

OPEN

Syntax: OPEN "filename" FOR OUTPUT|APPEND|INPUT|BINARY AS #n
Source: pb_cg_emit_open (pb_codegen.c:6072)

Description

Opens a file and assigns it a file number #n. The mode determines the Win32 access flags and creation disposition.

Parameters

ParameterDescription
filenamePath to the file (STRING literal or variable)
modeOUTPUT (write, create new), APPEND (write, keep existing), INPUT (read), BINARY (read+write)
nInteger file number (1-255)

Example

OPEN "data.txt" FOR OUTPUT AS #1
OPEN "log.txt" FOR APPEND AS #2
OPEN "input.txt" FOR INPUT AS #3
OPEN "data.bin" FOR BINARY AS #4

Generated Assembly

mov    rcx, filename_ptr               ; lpFileName
mov    rdx, <desired_access>            ; see table below
mov    r8, 0                            ; dwShareMode = 0
mov    r9, 0                            ; lpSecurity = NULL
mov    [rsp + 32], <creation>           ; dwCreationDisposition
mov    [rsp + 40], 128                  ; FILE_ATTRIBUTE_NORMAL
mov    [rsp + 48], 0                    ; hTemplateFile = NULL
call   [__imp_CreateFileA]
mov    [rbp - handle_offset], rax       ; save file handle

; FOR APPEND: seek to end additionally
mov    rcx, [rbp - handle_offset]
xor    rdx, rdx                         ; distance = 0
mov    r8, 0                            ; unused
mov    r9, 2                            ; FILE_END
call   [__imp_SetFilePointer]

Access Modes

ModedwDesiredAccessdwCreationDisposition
INPUT0x80000000 (GENERIC_READ)3 (OPEN_EXISTING)
OUTPUT0x40000000 (GENERIC_WRITE)2 (CREATE_ALWAYS)
APPEND0x40000000 (GENERIC_WRITE)4 (OPEN_ALWAYS)
BINARY0xC0000000 (GENERIC_READ|WRITE)4 (OPEN_ALWAYS)

PRINT #n

Syntax: PRINT #n, expr
Source: pb_cg_emit_writefile_handle (pb_codegen.c:5182)

Description

Writes formatted text to file #n using WriteFile with the stored file handle. The expression is formatted identically to console PRINT.

Parameters

ParameterDescription
nThe file number to write to
exprAny printable expression (STRING, numeric, or comma/semicolon separated list)

Example

OPEN "output.txt" FOR OUTPUT AS #1
PRINT #1, "Hello World"
PRINT #1, "Answer: "; 42
CLOSE #1

Generated Assembly

; Format expression (same as console PRINT)
; Then WriteFile using saved file handle:
mov    rcx, [rbp - handle_offset]        ; file handle (NOT GetStdHandle)
mov    rdx, [rbp - print_ptr_offset]     ; buffer
mov    r8, [rbp - print_len_offset]      ; byte count
lea    r9, [rbp - written_offset]        ; &bytesWritten
mov    [rsp + 32], 0                     ; lpOverlapped = NULL
call   [__imp_WriteFile]

INPUT #n

Syntax: INPUT #n, variable$
Source: pb_cg_emit_read_file_line (pb_codegen.c:5291)

Description

Reads a line of text from file #n into a STRING variable. The file must be opened for INPUT or BINARY.

Parameters

ParameterDescription
nThe file number to read from
variable$A STRING variable to receive the line

Example

OPEN "input.txt" FOR INPUT AS #1
LOCAL line$ AS STRING
INPUT #1, line$
PRINT line$
CLOSE #1

Generated Assembly

mov    rcx, [rbp - handle_offset]        ; file handle
lea    rdx, [rbp - buffer_offset]         ; read buffer
mov    r8, <max_count>                   ; max bytes to read
lea    r9, [rbp - file_read_count]        ; &bytesRead
mov    [rsp + 32], 0
call   [__imp_ReadFile]
; NUL-terminate:
mov    r10, [rbp - file_read_count]       ; bytes read
lea    r11, [rbp - buffer_offset]
add    r11, r10
mov    byte [r11], 0                      ; buffer[bytesRead] = 0

GET (Binary Read)

Syntax: GET #n, [position,] variable
Source: pb_cg_emit_get (pb_codegen.c:780)

Description

Reads binary data from file #n into a variable. If position is specified, the file pointer is first set to that 1-based record position.

Parameters

ParameterDescription
nThe file number (must be opened for BINARY)
position(Optional) 1-based record position
variableVariable to read into (size determines bytes read)

Example

LOCAL val AS LONG
OPEN "data.bin" FOR BINARY AS #1
GET #1, 3, val          ' read 4-byte LONG at record 3
CLOSE #1

Generated Assembly

; Optional SEEK for record position
; Get target address -> RDX
mov    rcx, [rbp - handle_offset]
mov    rdx, target_ptr                   ; buffer
mov    r8, <element_size>               ; bytes to read
lea    r9, [rbp - file_read_count]
mov    [rsp + 32], 0
call   [__imp_ReadFile]

PUT (Binary Write)

Syntax: PUT #n, [position,] variable
Source: pb_cg_emit_put (pb_codegen.c:880)

Description

Writes binary data from a variable to file #n. If position is specified, the file pointer is first set to that 1-based record position.

Parameters

ParameterDescription
nThe file number (must be opened for BINARY)
position(Optional) 1-based record position
variableVariable whose data is written

Example

LOCAL val AS LONG
val = 12345
OPEN "data.bin" FOR BINARY AS #1
PUT #1, 1, val          ' write 4-byte LONG at record 1
CLOSE #1

Generated Assembly

mov    rcx, [rbp - handle_offset]
lea    rdx, [rbp - buffer_offset]        ; source data
mov    r8, <element_size>               ; bytes to write
lea    r9, [rbp - written_offset]
mov    [rsp + 32], 0
call   [__imp_WriteFile]

SEEK

Syntax: SEEK #n, position
Source: pb_cg_emit_seek (pb_codegen.c:6132)

Description

Sets the file pointer to a specific 1-based record position for subsequent GET/PUT operations. Internally converts to a 0-based byte offset and calls SetFilePointer.

Parameters

ParameterDescription
nThe file number
position1-based record position (numeric expression)

Example

OPEN "data.bin" FOR BINARY AS #1
SEEK #1, 10             ' jump to record 10
GET #1, rec             ' read record 10
CLOSE #1

Generated Assembly

; Convert 1-based position to 0-based
cmp    rax, 1
jge    __pb_seek_positive
xor    rax, rax                         ; clamp to 0
jmp    __pb_seek_ready
__pb_seek_positive:
sub    rax, 1                           ; 1-based -> 0-based
__pb_seek_ready:
mov    rcx, [rbp - handle_offset]
mov    rdx, rax                         ; distance to move
xor    r8, r8
xor    r9, r9
call   [__imp_SetFilePointer]

CLOSE #n

Syntax: CLOSE #n
Source: pb_cg_emit_close (pb_codegen.c:6115)

Description

Closes the file associated with #n by calling CloseHandle and zeroing out the stored handle. Safe to call on an already-closed file (no-op).

Parameters

ParameterDescription
nThe file number to close

Example

CLOSE #1                ' close file #1

Generated Assembly

mov    rcx, [rbp - handle_offset]
test   rcx, rcx
je     __pb_close_skip                  ; already closed
call   [__imp_CloseHandle]
mov    qword [rbp - handle_offset], 0   ; zero out handle
__pb_close_skip: