;license:MIT ;(c) 2018 by 4am ; ; Common functions across parsers ; ; Public functions: ; - ParseKeyValueText ; - IncAndGetChar ; ;------------------------------------------------------------------------------ ; 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 ; $FE/$FF clobbered ;------------------------------------------------------------------------------ ParseKeyValueText +PARAMS_ON_STACK 5 +LDPARAM 1 +STAY @store1 +STAY @store2 +LDPARAM 3 +STAY $FE ldy #5 lda (PARAM),y sta @maxLength 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 @store1 !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 .parseKeyValueDone 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 +HIDE_NEXT_2_BYTES @useMaxLength @maxLength=*+1 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 @store2 !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 ; ; 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 .parseKeyValueDone rts