gKeyLen = $3F00 gKey = $3F01 gValLen = $3F80 gVal = $3F81 ;------------------------------------------------------------------------------ ; ParseKeyValueText ; parse buffer with KEY=VALUE lines of text into an okvs ; keys and values limited to 127 characters, which should be enough for anyone ; ; in: stack contains 5 bytes of parameters: ; +1 [word] handle to storage space ; +3 [word] handle to data buffer ; +5 [byte] max length for okvs records (or 0) ; out: all registers and flags clobbered ; $3F00..$3FFF clobbered ; $00/$01 clobbered ; $02/$03 clobbered ; $04/$05 has the address of the next available byte after the okvs ;------------------------------------------------------------------------------ !zone { ParseKeyValueText +PARAMS_ON_STACK 5 ldy #1 lda (PARAM),y sta .initStore sta .appendStore iny lda (PARAM),y sta .initStore+1 sta .appendStore+1 iny lda (PARAM),y sta $FE iny lda (PARAM),y sta $FF iny lda (PARAM),y sta .useMaxLength+1 lda ($FE) pha ldy #1 lda ($FE),y tay pla sec sbc #$01 sta $FE bcs + dey + sty $FF jsr okvs_init ; reset key/value store .initStore !word $FDFD ; SMC ldy #$00 ; index into ($FE) pointing to current character .newKey ldx #$00 ; X = index into current key .gatherKey jsr IncAndGetChar and #$7F ; keys get their high bit stripped cmp #$23 ; '#' is starts a comment (until CR) beq .skipComment cmp #$3D ; '=' ends the key beq .endKey cmp #$0D ; found CR before '=', ignore key and start over (also handles blank lines) beq .newKey cmp #$5B ; '[' ends the parsing beq .exit sta gKey,x inx bpl .gatherKey .endKey stx gKeyLen ldx #$00 ; now X = index into the current value .gatherValue jsr IncAndGetChar ; note: values do NOT get their high bit stripped cmp #$0D ; CR ends the value beq .endValue cmp #$00 ; null also ends the value beq .endValue sta gVal,x inx bpl .gatherValue .endValue stx gValLen cpx #1 bne .useMaxLength lda gVal and #1 sta gVal ; single-character values get converted to #$00 or #$01 in prefs store lda #0 !byte $2C .useMaxLength lda #$FD ; SMC sta .appendMaxLength ; all other values get upgraded to max_length so we can update them in place phy ; okvs functions clobber everything but we need Y jsr okvs_append .appendStore !word $FDFD ; SMC !word gKeyLen !word gValLen .appendMaxLength !byte $FD ; SMC ply bra .newKey .skipComment ; skip to CR jsr IncAndGetChar cmp #$0D ; CR bne .skipComment bra .newKey IncAndGetChar iny bne + inc $FF + lda ($FE),y .exit rts }