News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Monospace algo that handles quoted text.

Started by hutch--, May 04, 2019, 03:44:51 PM

Previous topic - Next topic

hutch--

This algo changes any combination of white space to single spaces and returns the number of space delimited arguments in rcx. It handles both single and double quotes in the same way that MASM does, double quotes can handle single quoted, single quoted can handle double quotes. This is so quoted text is not modified by the code for non quoted text. In many circumstances it will detect unmatched quote errors but nothing can make it idiot proof so I have not bothered to try. Apart from its general purpose use, I am aiming it at processing command line arguments into an array so that sections of quoted text get loaded accurately into a single array member but I have not finalised the design for that yet.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

NOSTACKFRAME

monospace_args proc
  ; -------------------------------------------------------
  ; monospace arguments in string except in quoted text
  ; double quote pairs can contain single quotes and spaces
  ; single quote pairs can contain double quotes and spaces
  ; arg count is returned in rcx
  ; -------------------------------------------------------
  ; -----------------------------------
  ; arg1 = src (rcx) : arg2 = dst (rdx)
  ; -----------------------------------

    xor r11, r11                            ; zero the arg counter

    sub rcx, 1

  ftrim:
    add rcx, 1
    cmp BYTE PTR [rcx], 0
    je bye
    cmp BYTE PTR [rcx], 9
    je ftrim
    cmp BYTE PTR [rcx], 32
    je ftrim
    sub rcx, 1

    add r11, 1                              ; increment the arg counter

  lpst:
    add rcx, 1
    cmp BYTE PTR [rcx], 0                   ; exit on zero
    je bye
    cmp BYTE PTR [rcx], 32                  ; test for space
    je spc
    cmp BYTE PTR [rcx], 34                  ; test for double quote
    je dqot
    cmp BYTE PTR [rcx], 39                  ; test for single quote
    je sqot
    movzx rax, BYTE PTR [rcx]               ; copy byte and write to destination
    mov BYTE PTR [rdx], al
    add rdx, 1
    jmp lpst

  spc:
    mov BYTE PTR [rdx], 32                  ; write single space
    add rdx, 1                              ; increment rdx by 1
    jmp ftrim                               ; front trim any other white spaces

  ; -----------------------------------------

  dqot:                                     ; start double quote loop
    mov BYTE PTR [rdx], 34
    mov BYTE PTR [rdx+1], 32
    add rdx, 1

  @@:
    add rcx, 1
    cmp BYTE PTR [rcx], 0
    je qterr
    cmp BYTE PTR [rcx], 34                  ; test for next double quote
    je wdq
    movzx rax, BYTE PTR [rcx]
    mov BYTE PTR [rdx], al
    add rdx, 1
    jmp @B

  wdq:                                      ; write trailing double quote
    mov BYTE PTR [rdx], 34
    mov BYTE PTR [rdx+1], 32
    add rdx, 2
    jmp ftrim

  ; -----------------------------------------

  sqot:                                     ; start single quote loop
    mov BYTE PTR [rdx], 39
    mov BYTE PTR [rdx+1], 32
    add rdx, 1

  @@:
    add rcx, 1
    cmp BYTE PTR [rcx], 0
    je qterr
    cmp BYTE PTR [rcx], 39                  ; test for next single quote
    je wsq
    movzx rax, BYTE PTR [rcx]
    mov BYTE PTR [rdx], al
    add rdx, 1
    jmp @B

  wsq:                                      ; write trailing single quote
    mov BYTE PTR [rdx], 39
    mov BYTE PTR [rdx+1], 32
    add rdx, 2
    jmp ftrim

  ; -----------------------------------------

  qterr:
    xor rax, rax                            ; return zero on quote error (missing 2nd quote)
    ret

  bye:
    cmp BYTE PTR [rdx-1], 32                ; test for trailing space
    jne @F
    sub rdx, 1                              ; if trailing space, shift terminator back 1
  @@:
    mov BYTE PTR [rdx], 0                   ; terminate
    mov rax, 1                              ; return non zero on success
    mov rcx, r11                            ; return the arg count in rcx
    ret

monospace_args endp

STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤