include qlib.inc ;setup
include dos.inc
include string.inc
include alloc.inc
include math.inc
include conio.inc
include stdio.inc
include key.inc
;FIX v2.00 Beta #8 : this has been heavily updated
; scanf() can now input data on multiple lines
.data
r8 REAL8 ? ;used in scanf %f thingy
noscans dd ? ;no of scans
tns dd ? ;total # of scans (w/ scanf())
.code
scanf proc,format:dword,vars:vararg
;ADDED in Ver 2.0
local tsiz:dword ;TOTAL size
local asiz:dword ;totol allocated
local bsiz:dword ;size of current block in use
local hand:dword ;memory
bufsiz equ 1024
pushad
lea ebx,vars
mov esi,format
mov tns,0
@@top:
mov al,[esi]
cmp al,0
.if zero?
popad
mov eax,tns
ret
.endif
mov tsiz,0 ;total size (of chars inside block)
mov asiz,bufsiz ;actual size (of byte alloced currently)
callp malloc,bufsiz
.if eax==NULL
jmp bad
.endif
mov hand,eax
mov bsiz,0 ;current buffer size
@@:
callp _getch
.if al==KB_ENTER
callp putch,13 ;FIX : v2.00 Beta #7 : these were needed
callp putch,10 ; "
mov eax,hand
add eax,tsiz
mov bptr[eax],0
mov edi,hand
call _sscanf
push eax
mov eax,noscans
add tns,eax
callp free,hand
pop eax
.if eax==ERROR
jmp bad
.endif
jmp @@top
.endif
.if al==KB_ESC ;ignore this line
callp putch,'\'
callp putch,13
callp putch,10
callp free,hand
jmp @@top
.endif
.if ((al==KB_BS) || (ax==KB_LEFT)) && tsiz ;BackSpace FIX : v2.04 Beta #2
callp putch,8 ; this was using old key codes
callp putch,32 ; and so was gets()
callp putch,8
dec tsiz
jmp @b
.endif
.if (al>31)
mov cl,al
inc tsiz
inc bsiz
.if bsiz > bufsiz
add asiz,bufsiz
invoke realloc,hand,asiz
mov hand,eax
.if eax==ERROR
jmp bad
.endif
.endif
mov eax,hand
add eax,tsiz
dec eax ;pt to new loc
mov [eax],cl
callp putch,cl
.endif
jmp @b
bad:
popad
mov eax,tns
ret
scanf endp
sscanf proc,buf:dword,format:dword,vars:vararg
;ADDED in Ver 1.1
pushad
mov esi,format
mov edi,buf
lea ebx,vars
call _sscanf
popad
mov eax,noscans
ret
sscanf endp
;in : esi=format string
; : edi=buffer (input data)
; : ebx=varargs
;out: noscans = no of scans successful and data filled in varargs
; seeks thru esi until hits %? and then seeks thru edi until it's not a space
_sscanf:
mov noscans,0
.if bptr[edi]==0
jmp __end ;no more data
.endif
@@top:
;seek for %?
lodsb
cmp al,0
jz __done
cmp al,'%'
jz @@per
@@per1:
inc edi
.if bptr[edi]==0
jmp __end ;no more data
.endif
jmp @@top
@@per: ; % in use
lodsb
.if al=='s'
callp strcpy,dptr ss:[ebx],edi
callp strlen,edi
add edi,eax
inc edi ;there better be more stuff after the 0 if you still have more
;fields to fill in
add ebx,4
.if bptr[edi]==0
jmp __end ;no more data
.endif
jmp @@top
.endif
cmp al,0
jz __done ;not enough stuff!
cmp al,'i'
jz @@peru
cmp al,'u'
jz @@peru
cmp al,'b'
jz @@perb
cmp al,'d'
jz @@perd
cmp al,'x'
jz @@perx
cmp al,'X'
jz @@perx
cmp al,'c'
jz @@perc
cmp al,'o'
jz @@pero
cmp al,'e'
jz @@perf
cmp al,'f'
jz @@perf
jmp @@per1 ;ignore % and go on
@@peru:
@@perd:
invoke str2num,edi
mov ecx,ss:[ebx]
mov [ecx],eax
jmp addstr
@@perb:
invoke str2numb,edi
mov ecx,ss:[ebx]
mov [ecx],eax
jmp addstr
@@perx:
invoke str2numx,edi
mov ecx,ss:[ebx]
mov [ecx],eax
jmp addstr
@@pero:
invoke str2numo,edi
mov ecx,ss:[ebx]
mov [ecx],eax
jmp addstr
@@perc:
mov ecx,ss:[ebx]
mov al,[edi]
mov [ecx],al
inc edi
add ebx,4 ;no byte pushes possible
inc noscans
.if bptr[edi]==0
jmp __end ;no more data
.endif
jmp @@top
@@perf:
invoke atof,edi
mov ecx,ss:[ebx]
.if _math_typ
mov [ecx],eax ;Watcom style
mov [ecx+4],edx ;EAX:EDX = double
.else
;borland style
fstp r8
fwait
mov eax,dptr [r8]
mov [ecx],eax
mov eax,dptr [r8+4]
mov [ecx+4],eax
.endif
.if !_str2num_siz_ ;bad conversion
jmp __done
.endif
add ebx,4 ;move to next var. ;FIX v2.00 Beta #8 : this was 8
add edi,_str2num_siz_ ;size of last str2num call
inc noscans
.if bptr[edi]==0
jmp __end ;no more data
.endif
jmp @@top
__end:
xor eax,eax
ret
__done:
mov eax,ERROR
ret
addstr:
.if !_str2num_siz_ ;bad conversion
jmp __done
.endif
inc noscans
add ebx,4 ;move to next var.
add edi,_str2num_siz_ ;size of last str2num call
.if bptr[edi]==0
jmp __end ;no more data
.endif
jmp @@top
end