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
|
# From assembly source-files
|
||||||
S_OBJS = _cwd.o \
|
S_OBJS = _cwd.o \
|
||||||
|
_environ.o \
|
||||||
_fdesc.o \
|
_fdesc.o \
|
||||||
_file.o \
|
_file.o \
|
||||||
_fopen.o \
|
_fopen.o \
|
||||||
@ -112,6 +113,7 @@ S_OBJS = _cwd.o \
|
|||||||
fwrite.o \
|
fwrite.o \
|
||||||
getcpu.o \
|
getcpu.o \
|
||||||
getcwd.o \
|
getcwd.o \
|
||||||
|
getenv.o \
|
||||||
isalnum.o \
|
isalnum.o \
|
||||||
isalpha.o \
|
isalpha.o \
|
||||||
isblank.o \
|
isblank.o \
|
||||||
@ -140,11 +142,13 @@ S_OBJS = _cwd.o \
|
|||||||
oserrcheck.o \
|
oserrcheck.o \
|
||||||
printf.o \
|
printf.o \
|
||||||
putchar.o \
|
putchar.o \
|
||||||
|
putenv.o \
|
||||||
rand.o \
|
rand.o \
|
||||||
raise.o \
|
raise.o \
|
||||||
remove.o \
|
remove.o \
|
||||||
rename.o \
|
rename.o \
|
||||||
scanf.o \
|
scanf.o \
|
||||||
|
searchenv.o \
|
||||||
setjmp.o \
|
setjmp.o \
|
||||||
signal.o \
|
signal.o \
|
||||||
sigtable.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