4cade/src/parse.common.a

271 lines
8.0 KiB
Plaintext
Raw Permalink Normal View History

2018-10-23 19:44:06 +00:00
;license:MIT
;(c) 2018-9 by 4am
2018-10-23 19:44:06 +00:00
;
; generic key/value text parser
;
; Public functions:
; - ParseKeyValueList
2019-06-30 19:10:09 +00:00
; - IncAndGetChar
2018-10-23 19:44:06 +00:00
;
;------------------------------------------------------------------------------
; ParseKeyValueList
; parse buffer with KEY=VALUE lines of a text file into an okvs
; keys and values limited to 127 characters, which should be enough for anyone
; if '=' is missing, key is kept and value is a 0-length string
; blank lines are ignored
; '#' character at beginning of line is a comment, entire line is ignored
; '[' character at beginning of line exits the parser
;
2019-10-08 03:20:23 +00:00
; in: stack contains 5 bytes of parameters:
2018-10-23 19:44:06 +00:00
; +1 [word] handle to storage space for okvs
; +3 [word] handle to buffer containing contents of text file
2018-11-10 15:08:14 +00:00
; +5 [byte] max length for okvs records (or 0)
2018-10-23 19:44:06 +00:00
; out: all registers and flags clobbered
; $1F00..$1FFF clobbered
; $00/$01 clobbered
; $02/$03 clobbered
; $04/$05 has the address of the next available byte after the okvs
; $FE/$FF clobbered
;------------------------------------------------------------------------------
ParseKeyValueList
2018-11-10 15:08:14 +00:00
+PARAMS_ON_STACK 5
2018-10-23 19:44:06 +00:00
2021-10-13 22:58:26 +00:00
+LDPARAM 1 ; not LDPARAMPTR, SetKeyPtr requires A/Y!
2020-03-24 20:30:14 +00:00
+ST16 @store2
2019-09-24 00:01:42 +00:00
jsr SetKeyPtr
2018-11-10 15:08:14 +00:00
ldy #5
lda (PARAM),y
sta @maxLength
2018-10-23 19:44:06 +00:00
ldy #$00 ; index into ($FE) pointing to current character
@newkey ldx #$00 ; X = index into current key
stx gValLen ; initialize value length (in case this line has no value)
2019-09-24 00:01:42 +00:00
beq @emptyline ; always branches
@skipLine ; skip to CR
jsr IncAndGetChar
2020-03-23 01:58:26 +00:00
cmp #$0A ; CR
2019-09-24 00:01:42 +00:00
bne @skipLine
@emptyline
2018-10-23 19:44:06 +00:00
jsr IncAndGetChar
2020-03-23 01:58:26 +00:00
cmp #$0A ; CR in first position (blank line) -> no key
2019-09-24 00:01:42 +00:00
beq @emptyline
2018-10-23 19:44:06 +00:00
cmp #$23 ; '#' starts a comment -> no key, skip to CR
beq @skipLine
cmp #$5B ; '[' ends the parsing
beq .parseKeyValueDone
bne @appendToKey
@gatherKey
jsr IncAndGetChar
2020-03-23 01:58:26 +00:00
cmp #$0A ; CR -> finalize key, no value
2018-10-23 19:44:06 +00:00
beq @finalizeKey
cmp #$3D ; '=' -> finalize key, start gathering value
beq @finalizeKey
@appendToKey
sta gKey,x
inx
bpl @gatherKey
@finalizeKey
stx gKeyLen
2020-03-23 01:58:26 +00:00
cmp #$0A
2018-10-23 19:44:06 +00:00
beq @storeInOKVS
ldx #$00 ; now X = index into the current value
@gatherValue
jsr IncAndGetChar
2020-03-23 01:58:26 +00:00
cmp #$0A ; CR -> finalize value
2018-10-23 19:44:06 +00:00
beq @finalizeValue
sta gVal,x
inx
bpl @gatherValue
@finalizeValue
stx gValLen
@storeInOKVS
tya
pha ; okvs functions clobber everything but we need Y
jsr okvs_append
@store2 !word $FDFD ; SMC
!word gKeyLen
!word gValLen
2018-11-10 15:08:14 +00:00
@maxLength
!byte $FD ; SMC
2018-10-23 19:44:06 +00:00
pla
tay
clc
bcc @newkey ; always branches
2019-09-24 00:01:42 +00:00
;------------------------------------------------------------------------------
; SetKeyPtr
;
; in: PARAM set
; out: okvs initialised
; ($FE) -> buffer
;------------------------------------------------------------------------------
SetKeyPtr
jsr okvs_init ; reset key/value store
2019-11-27 21:51:43 +00:00
+LDPARAMPTR 3, $FE
2019-09-24 00:01:42 +00:00
2019-11-27 21:51:43 +00:00
ldy #0
2019-09-24 00:01:42 +00:00
lda ($FE),y
tax
bne +
2019-11-27 21:51:43 +00:00
iny
lda ($FE),y
sta $FF
dec $FF
+ dex
2019-09-24 00:01:42 +00:00
stx $FE
rts
2018-10-23 19:44:06 +00:00
;------------------------------------------------------------------------------
; IncAndGetChar
;
; in: Y = index into ($FE)
; ($FE) -> buffer
; out: A contains next byte from buffer
; Y incremented
; $FF possibly incremented
;------------------------------------------------------------------------------
IncAndGetChar
iny
bne +
inc $FF
+ lda ($FE),y
cmp #$0D ; CR - hide it
beq IncAndGetChar
2018-10-23 19:44:06 +00:00
.parseKeyValueDone
rts
2021-10-23 04:53:23 +00:00
;------------------------------------------------------------------------------
; okvs_append
;
; in: stack contains 7 bytes of parameters:
; +1 [word] handle to storage space
; +3 [word] address of key
; +5 [word] address of value
; +7 [byte] maximum length of value (or 0 to fit)
; out: (new record count is not returned because no one cares)
; all registers clobbered
; $00/$01 clobbered
; $02/$03 clobbered
; $04/$05 has the address of the next available byte after the new record
; $08/$09 clobbered
;------------------------------------------------------------------------------
okvs_append
+PARAMS_ON_STACK 7
jsr GetStoreAddress
; PTR -> store
; Y = 0
lda (PTR),y ; A = number of keys in store
sta WINDEX
iny
lda (PTR), y
sta WINDEX+1
inc WINDEX
bne +
inc WINDEX+1
+
dey
lda WINDEX
sta (PTR),y ; increment number of keys
lda WINDEX+1
iny
sta (PTR),y
iny
lda (PTR),y ; get address of next free space
tax
iny
lda (PTR),y
sta PTR+1
sta SAVE+1
stx PTR
stx SAVE
; PTR -> new record
; SAVE -> new record
jsr incptr
; PTR -> space for new key
+LDPARAMPTR 3, SRC ; SRC -> new key to copy
ldy #0
lda (SRC),y
tay
tax
- lda (SRC),y ; copy new key
sta (PTR),y
dey
cpy #$FF
bne -
;;sec
txa
adc PTR ; update PTR to byte after copied key
sta PTR
bcc +
inc PTR+1
+ ; PTR -> space for new value
+LDPARAMPTR 5, SRC ; SRC -> new value to copy
iny ;;ldy #7
lda (PARAM),y ; get max length of value
tax
bne +
tay
lda (SRC),y ; no max, use actual length instead
tax
+ inx
tay
- lda (SRC),y
sta (PTR),y
dey
cpy #$FF
bne -
txa
clc
adc PTR
tax
lda PTR+1
adc #0
pha
+ jsr GetStoreAddress
; PTR -> store
pla
ldy #3
sta (PTR),y ; update next-free-space pointer in head
dey
txa
sta (PTR),y
sec
sbc SAVE
ldy #0
sta (SAVE),y ; set record length
rts
2021-11-18 04:54:51 +00:00
;------------------------------------------------------------------------------
; okvs_init
;
; in: A/Y = handle to storage space
; out: $00/$01 clobbered
; $02/$03 clobbered
; all registers clobbered
;------------------------------------------------------------------------------
okvs_init
jsr GetStoreAddressFromAY
; PTR -> store
; Y = 0
tya
sta (PTR),y ; set number of keys in store to 0 (word)
iny
sta (PTR),y
iny ; set next-free-space pointer to store + 4
ldx PTR+1
lda PTR
clc
adc #$04
bcc +
inx
+ sta (PTR),y
iny
txa
sta (PTR),y
rts