mirror of
https://github.com/cc65/cc65.git
synced 2025-01-12 17:30:50 +00:00
Added environment routines
git-svn-id: svn://svn.cc65.org/cc65/trunk@3483 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
142636504f
commit
e0319679f0
@ -79,6 +79,7 @@ C_OBJS = _afailed.o \
|
||||
|
||||
# From assembly source-files
|
||||
S_OBJS = _cwd.o \
|
||||
_environ.o \
|
||||
_fdesc.o \
|
||||
_file.o \
|
||||
_fopen.o \
|
||||
@ -112,6 +113,7 @@ S_OBJS = _cwd.o \
|
||||
fwrite.o \
|
||||
getcpu.o \
|
||||
getcwd.o \
|
||||
getenv.o \
|
||||
isalnum.o \
|
||||
isalpha.o \
|
||||
isblank.o \
|
||||
@ -140,11 +142,13 @@ S_OBJS = _cwd.o \
|
||||
oserrcheck.o \
|
||||
printf.o \
|
||||
putchar.o \
|
||||
putenv.o \
|
||||
rand.o \
|
||||
raise.o \
|
||||
remove.o \
|
||||
rename.o \
|
||||
scanf.o \
|
||||
searchenv.o \
|
||||
setjmp.o \
|
||||
signal.o \
|
||||
sigtable.o \
|
||||
|
30
libsrc/common/_environ.s
Normal file
30
libsrc/common/_environ.s
Normal file
@ -0,0 +1,30 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2005-04-21
|
||||
;
|
||||
; extern char** _environ;
|
||||
;
|
||||
;
|
||||
; __environ is a pointer to the environment.
|
||||
; __envcount is the number of entries in the environment.
|
||||
; __envsize is the size of the allocated array.
|
||||
;
|
||||
; The maximum number of environment entries is 64. putenv() will set errno
|
||||
; to ENOMEM when trying to increase the number beyond this limit.
|
||||
;
|
||||
|
||||
.export __environ, __envcount, __envsize
|
||||
.import initenv
|
||||
.constructor env_init
|
||||
|
||||
env_init := initenv
|
||||
|
||||
.bss
|
||||
|
||||
__environ:
|
||||
.addr 0
|
||||
__envcount:
|
||||
.byte 0
|
||||
__envsize:
|
||||
.byte 0
|
||||
|
||||
|
46
libsrc/common/getenv.s
Normal file
46
libsrc/common/getenv.s
Normal file
@ -0,0 +1,46 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2005-04-21
|
||||
;
|
||||
; char* __fastcall__ getenv (const char* name);
|
||||
;
|
||||
; Beware: putenv() knows about zero page usage in this module!
|
||||
;
|
||||
|
||||
.export _getenv
|
||||
.import __environ, __envcount
|
||||
.import searchenv
|
||||
.import return0
|
||||
.import ptr1:zp, ptr3:zp, tmp1:zp
|
||||
|
||||
.code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; getenv()
|
||||
|
||||
.proc _getenv
|
||||
|
||||
sta ptr1
|
||||
stx ptr1+1 ; Save name
|
||||
|
||||
; Search for the string in the environment. searchenv will set the N flag if
|
||||
; the string is not found, otherwise X contains the index of the entry, ptr3
|
||||
; contains the entry and Y the offset of the '=' in the string.
|
||||
|
||||
jsr searchenv
|
||||
bpl found
|
||||
jmp return0 ; Not found, return NULL
|
||||
|
||||
; Found the entry. Calculate the pointer to the right side of the environment
|
||||
; variable. Because we want to skip the '=', we will set the carry.
|
||||
|
||||
found: ldx ptr3+1 ; High byte of result
|
||||
tya
|
||||
sec
|
||||
adc ptr3
|
||||
bcc @L9
|
||||
inx
|
||||
@L9: rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
198
libsrc/common/putenv.s
Normal file
198
libsrc/common/putenv.s
Normal file
@ -0,0 +1,198 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2005-04-21
|
||||
;
|
||||
; int putenv (char* s);
|
||||
;
|
||||
; Note: The function will place s into the environment, *not* a copy!
|
||||
;
|
||||
|
||||
.export _putenv
|
||||
.import _malloc, _free
|
||||
.import searchenv, copyenvptr
|
||||
.import __environ, __envcount, __envsize
|
||||
.import seterrno, return0
|
||||
.import ptr1:zp, ptr2:zp, ptr3:zp, tmp1:zp
|
||||
|
||||
.include "errno.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
.code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; putenv()
|
||||
|
||||
.proc _putenv
|
||||
|
||||
sta ptr1
|
||||
sta name
|
||||
stx ptr1+1 ; Save name
|
||||
stx name+1
|
||||
|
||||
; Loop over the name to find the '='. If there is no '=', set errno to EINVAL
|
||||
; and return an error.
|
||||
|
||||
ldy #$FF
|
||||
@L0: iny
|
||||
lda (ptr1),y
|
||||
bne @L1
|
||||
lda #EINVAL
|
||||
jmp error ; End of string without '=' found
|
||||
@L1: cmp #'='
|
||||
bne @L0
|
||||
|
||||
; Remember the offset of the equal sign and replace it by a zero.
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
phy
|
||||
stz (ptr1),y
|
||||
.else
|
||||
sty tmp1
|
||||
lda #$00
|
||||
sta (ptr1),y
|
||||
.endif
|
||||
|
||||
; Search for the string in the environment. searchenv will set the N flag if
|
||||
; the string is not found, otherwise X contains the index of the entry, ptr2
|
||||
; contains the entry and Y the offset of the '=' in the string. ptr3 will
|
||||
; point to the environment.
|
||||
|
||||
jsr searchenv
|
||||
|
||||
; Before doing anything else, restore the old environment string.
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
ply
|
||||
.else
|
||||
ldy tmp1
|
||||
.endif
|
||||
lda #'='
|
||||
sta (ptr1),y
|
||||
|
||||
; Check the result of searchenv
|
||||
|
||||
txa ; Did we find the entry?
|
||||
bpl addentry ; Jump if yes
|
||||
|
||||
; We didn't find the entry, so we have to add a new one. Before doing so, we
|
||||
; must check if the size of the _environ array must be increased.
|
||||
; Note: There must be one additional slot for the final NULL entry.
|
||||
|
||||
ldx __envcount
|
||||
inx
|
||||
cpx __envsize
|
||||
bcc addnewentry ; Jump if space enough
|
||||
|
||||
; We need to increase the size of the environ array. Calculate the new size.
|
||||
; We will not support a size larger than 64 entries, double the size with
|
||||
; each overflow, and the starting size is 8 entries.
|
||||
|
||||
lda __envsize
|
||||
bne @L2
|
||||
lda #4 ; Start with 4*2 entries
|
||||
@L2: asl a ; Double current size
|
||||
bmi nomem ; Bail out if > 64
|
||||
sta newsize ; Remember the new size
|
||||
|
||||
; Call malloc() and store the result in ptr2
|
||||
|
||||
asl a ; Make words
|
||||
ldx #$00
|
||||
jsr _malloc
|
||||
sta ptr2
|
||||
stx ptr2+1
|
||||
|
||||
; Check the result of malloc
|
||||
|
||||
ora ptr2+1
|
||||
beq nomem
|
||||
|
||||
; Copy the old environment pointer to ptr3, and the new one to __environ.
|
||||
|
||||
ldx #1
|
||||
@L3: lda __environ,x
|
||||
sta ptr3,x
|
||||
lda ptr2,x
|
||||
sta __environ,x
|
||||
dex
|
||||
bpl @L3
|
||||
|
||||
; Use the new size.
|
||||
|
||||
lda newsize
|
||||
sta __envsize
|
||||
|
||||
; Copy the old environment data into the new space.
|
||||
|
||||
lda __envcount
|
||||
asl a
|
||||
tay
|
||||
jmp @L5
|
||||
@L4: lda (ptr3),y
|
||||
sta (ptr2),y
|
||||
@L5: dey
|
||||
bpl @L4
|
||||
|
||||
; Free the old environment space
|
||||
|
||||
lda ptr3
|
||||
ldx ptr3+1
|
||||
jsr _free
|
||||
|
||||
; Since free() has destroyed ptr2, we need another copy ...
|
||||
|
||||
jsr copyenvptr ; Copy __environ to ptr2
|
||||
|
||||
; Bump the environment count and remember it in X. Add the final NULL entry.
|
||||
|
||||
addnewentry:
|
||||
inc __envcount
|
||||
ldx __envcount
|
||||
txa
|
||||
asl a
|
||||
tay
|
||||
lda #$00
|
||||
sta (ptr2),y
|
||||
iny
|
||||
sta (ptr2),y
|
||||
|
||||
; The index of the new entry is the old environment count.
|
||||
|
||||
dex
|
||||
txa
|
||||
|
||||
; Add the new entry to the slot with index in X. The pointer to the environment
|
||||
; is already in ptr2, either by a call to searchenv, or by above code.
|
||||
|
||||
addentry:
|
||||
asl a
|
||||
tay
|
||||
lda name
|
||||
sta (ptr2),y
|
||||
iny
|
||||
lda name+1
|
||||
sta (ptr2),y
|
||||
|
||||
; Done
|
||||
|
||||
jmp return0
|
||||
|
||||
; Error entries
|
||||
|
||||
nomem: lda #ENOMEM
|
||||
error: jsr seterrno
|
||||
lda #$FF ; Return -1
|
||||
tax
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; data
|
||||
|
||||
.bss
|
||||
|
||||
name: .addr 0 ; Pointer to name
|
||||
newsize: .byte 0 ; New environment size
|
||||
|
84
libsrc/common/searchenv.s
Normal file
84
libsrc/common/searchenv.s
Normal file
@ -0,0 +1,84 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2005-04-21
|
||||
;
|
||||
; Search the environment for a string.
|
||||
;
|
||||
|
||||
.export searchenv, copyenvptr
|
||||
.import __environ, __envcount
|
||||
.import ptr1:zp, ptr2:zp, ptr3:zp
|
||||
|
||||
.code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; searchenv:
|
||||
;
|
||||
; ptr1 must contain the string to search for. On exit, the N flag will tell
|
||||
; if the entry was found, and X will contain the index of the environment
|
||||
; string in the environment (a negative value if the entry was not found).
|
||||
; On success, ptr3 will contain the entry and Y the offset of the '=' within
|
||||
; the string.
|
||||
|
||||
.proc searchenv
|
||||
|
||||
; Copy the pointer to the environment to the zero page
|
||||
|
||||
jsr copyenvptr
|
||||
|
||||
; Loop over all environment entries trying to find the requested one.
|
||||
|
||||
ldx __envcount
|
||||
@L0: dex
|
||||
bmi @L9 ; Out of entries
|
||||
|
||||
; Since the maximum number of entries is 64, the index can only be 63, so
|
||||
; the following shift cannot overflow and the carry is clear.
|
||||
|
||||
txa
|
||||
asl a ; Mul by two for word access
|
||||
tay
|
||||
lda (ptr2),y
|
||||
sta ptr3
|
||||
iny
|
||||
lda (ptr2),y
|
||||
sta ptr3+1
|
||||
|
||||
; ptr1 points to name, ptr3 points to the next environment entry. Compare the
|
||||
; two. The following loop limits the length of name to 255 bytes.
|
||||
|
||||
ldy #$00
|
||||
@L1: lda (ptr1),y
|
||||
beq @L2 ; Jump on end of name
|
||||
cmp (ptr3),y
|
||||
bne @L0 ; Next environment entry
|
||||
iny
|
||||
bne @L1
|
||||
|
||||
; End of name reached, check if the environment entry contains a '=' char
|
||||
|
||||
@L2: lda (ptr3),y
|
||||
cmp #'='
|
||||
bne @L0 ; Next environment entry
|
||||
|
||||
; Done. The function result is in X and the N flag is set correctly.
|
||||
|
||||
@L9: rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; copyenvptr: Copy _environ to ptr2
|
||||
;
|
||||
|
||||
.proc copyenvptr
|
||||
|
||||
lda __environ
|
||||
sta ptr2
|
||||
lda __environ+1
|
||||
sta ptr2+1
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user