I have needed an algo of this type for a while, it scans a string and copies the user specified argument if it exists to buffer. It is a table based algo that has 3 delimiters set + anything over ascii 127. The normal delimiters are space comma and tab. There has been no serious effort to optimise the code but it appears to be working properly. Its basic design is it scans arguments until it matches the user specified arg number, then copies the next argument to the user specified buffer.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
align 4
ctbl \
db 2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 1,0,3,0,0,0,0,0,0,0,0,0,1,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
; 0 = OK char
; 1 = delimiting characters tab space "," & > ASCII 127
; 2 = ASCII zero
; 3 = quotation
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.code
retarg proc src:DWORD,dst:DWORD,num:DWORD
push ebx
push esi
push edi
mov esi, src
mov edi, dst
mov BYTE PTR [edi], 0 ; set destination buffer to zero length
xor ebx, ebx
; *********
; scan args
; *********
bcscan:
movzx eax, BYTE PTR [esi]
add esi, 1
cmp BYTE PTR [ctbl+eax], 1 ; delimiting character
je bcscan
cmp BYTE PTR [ctbl+eax], 2 ; ASCII zero
je quit
sub esi, 1
add ebx, 1
cmp ebx, num ; copy next argument if number matches
je cparg
gcscan:
movzx eax, BYTE PTR [esi]
add esi, 1
cmp BYTE PTR [ctbl+eax], 0 ; OK character
je gcscan
cmp BYTE PTR [ctbl+eax], 2 ; ASCII zero
je quit
cmp BYTE PTR [ctbl+eax], 3 ; quotation
je dblquote
jmp bcscan ; return to delimiters
dblquote:
add esi, 1
cmp BYTE PTR [esi], 0
je qterror
cmp BYTE PTR [esi], 34
jne dblquote
add esi, 1
jmp bcscan ; return to delimiters
; ********
; copy arg
; ********
cparg:
xor eax, eax
xor ecx, ecx
cmp BYTE PTR [esi+ecx], 34
je cpquote
@@:
mov al, [esi+ecx]
mov [edi+ecx], al
add ecx, 1
cmp BYTE PTR [ctbl+eax], 1
jl @B
jmp addzero
cpquote:
add esi, 1
@@:
mov al, [esi+ecx]
test al, al
jz qterror
cmp al, 34
je addzero
mov [edi+ecx], al
add ecx, 1
jmp @B
addzero:
mov BYTE PTR [edi+ecx], 0 ; append terminator
jmp quit
qterror:
mov eax, -2 ; quotation error
jmp TheEnd
quit:
xor eax, eax ; OK return value is ZERO
cmp BYTE PTR [edi], 0
jne TheEnd
mov eax, -1 ; no argument at user specified number
TheEnd:
pop edi
pop esi
pop ebx
ret
retarg endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Here is something like a production version of the algo. It has been renamed as ArgByNum and it operates in either single argument mode or in streaming mode. The attached example shows how both work.
[attachment deleted by admin]