Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

Obsah / Utility / TEXTFORM / FormToTextBuf

Zdrojový kód: INCLUDE\UTIL\TEXTFORM.INC, UTIL\TEXTFORM.ASM

Související:

Formátovací řetězec funkce FormToTextBuf
HexSToTextBuf   Zformátování čísla HEX do bufferu, malá písmena
HexCToTextBuf   Zformátování čísla HEX do bufferu, velká písmena
BinToTextBuf   Zformátování čísla BIN do bufferu
OctToTextBuf   Zformátování čísla OCT do bufferu
IntToTextBuf   Zformátování čísla INT se znaménkem do bufferu
UIntToTextBuf   Zformátování čísla INT bez znaménka do bufferu
FltToTextBuf   Zformátování desetinného čísla do bufferu
ExpSToTextBuf   Zformátování čísla s exponentem do bufferu, malé "e"
ExpCToTextBuf   Zformátování čísla s exponentem do bufferu, velké "E"
MixSToTextBuf   Zformátování smíšeného desetinného čísla do bufferu, malé "e"
MixCToTextBuf   Zformátování smíšeného desetinného čísla do bufferu, velké "E"
FormToTextBufN   Délka formátovaného textu

FormToTextBuf - Zformátování textu do bufferu

Funkce FormToTextBuf je zastřešením funkcí pro formátování čísel do bufferu. Zformátuje text s argumenty do textového bufferu. Funkce je obdobou funkce printf známé z jazyku C.


; -----------------------------------------------------------------------------
;                        Format text into text buffer
; -----------------------------------------------------------------------------
; INPUT:	EAX = callback value
;		EBX = size of source text to be formatted
;		ECX = pointer to nationality descriptor NATIONAL
;		EDX = source text to be formatted
;		ESI = remaining free space in destination buffer
;		EDI = destination buffer
;		EBP = callback function to read argument
;			INPUT:	EAX = callback value
;				EBX = formatting parameters with argument type
;				EDX = DWORD index in argument stack (0 to 255)
;			OUTPUT: CY=error, invalid argument index
;				EAX = width or precision parameter
;				EDX:EAX integer
;				EAX character UNICODE
;				ST0 floating point (only if NC)
;				EAX pointer to text UTF-8, EDX length of text
;			DESTROYS: EBX, ECX, EDX:EAX (if not returning a value)
; OUTPUT:	CY = error, invalid argument index
;		ESI = next remaining free space in buffer
;		EDI = next destination buffer
; NOTES:	64-bit integer or double float takes 2 DWORDs, extended double
;		takes 3 DWORDs and other numbers take 1 DWORD. Argument index
;		refers to index of DWORD argument, not to real argument number.
; 		To get user default nationality use DEFAULT_NAT macro.
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr EAX zpětnou hodnotu, která je předávána funkci sloužící k načtení hodnoty argumentu. Zpětnou hodnotou bývá zpravidla ukazatel na strukturu popisující objekt, který si vyžádal zformátování textu. Registr EBX obsahuje délku zdrojového textu ke zformátování. Registr ECX obsahuje ukazatel na popisovač národnostních informací NATIONAL. Ke zjištění implicitního popisovače národnostních informací lze použít makro DEFAULT_NAT. Registr EDX obsahuje ukazatel na zdrojový text ke zformátování. Zdrojový text je v kódu UTF-8. Registr ESI obsahuje čítač zbylého místa v cílovém bufferu a registr EDI ukazatel do cílového bufferu.

Registr EBP obsahuje ukazatel na zpětně volanou funkci sloužící k načtení hodnoty argumentu. Na vstupu funkce zpětného volání obsahuje registr EAX zpětnou hodnotu. Registr EBX obsahuje formátovací argumenty FORMPAR (ne ukazatel) spolu s typem požadovaného argumentu. Registr EDX obsahuje index požadovaného DWORD argumentu v rozsahu 0 až 255. Má-li argument větší velikost než DWORD, zabere v zásobníku místo pro více argumentů a registr EDX obsahuje index počátku argumentu zarovnaný na DWORD.

Na výstupu funkce zpětného volání je navracen příznak CY jako indikace chyby neplatného indexu argumentu. V případě této chyby se celá funkce FormToTextBuf ukončí s indikací chyby. Obsah ostatních registrů závisí na typu požadovaného argumentu. Parametr přesnosti nebo šířky je navracen v registru EAX, celé číslo v registrovém páru EDX:EAX, znak Unicode v registru EAX, desetinné číslo v registru ST0 a ukazatel na text v registru EAX, délka textu je obsažena v registru EDX. Obsahy nevyužitých registrů EAX, EBX, ECX a EDX mohou být funkcí zrušeny.

Na výstupu funkce FormToTextBuf je nastaven příznak chyby CY v případě, že funkce zpětného volání navrátila chybu neplatného indexu argumentu. Registry ESI a EDI na výstupu ukazují na novou ukládací pozici. Funkce předpokládá, že koprocesor je v implicitním nastavení - přesnost 64 bitů, zaokrouhlení k nejbližšímu.


; Local variables (ebp+N are read-only variables):
;
;  EAX = temporary register
;  EBX = formatting parameters
;  ECX = remaining size of source text
;  EDX = source text
;  ESI = remaining free space in destination buffer
;  EDI = destination buffer

%define		FORMVal		ebp+16	; (4) callback value
%define		FORMNat		ebp+8	; (4) pointer to nationality
%define		FORMCall	ebp+0	; (4) callback function
%define		FORMInx		ebp-1	; (1) current argument index
%define		FORMExpInx	ebp-2	; (1) explicit argument index
%define		FORMNum		ebp-3	; (1) read number
%define		FORMFlag	ebp-4	; (1) flags (see below)
%define		FORMFlagNum	FORMFlag; (2) flags and number
%define		FORMForm	ebp-8	; (4) formatting parameters

%define		FORMStack	8	; stack size

; Flags:
%define		FORMFLAG_NUM	B0	; start read number
%define		FORMFLAG_PREC	B1	; precision has been started
%define		FORMFLAG_EXP	B2	; explicit argument index valid
%define		FORMFLAG_INXW	B3	; get width from arguments
%define		FORMFLAG_INXP	B4	; get precision from arguments
%define		FORMFLAG_PAR	B5	; get parameter "*"
%define		FORMFLAG_PSET	B6	; precision has been set

Funkce používá registry jako lokální proměnné s tímto významem: EAX je přechodný registr, EBX jsou formátovací parametry, ECX je zbývající velikost zdrojového textu, EDX ukazatel zdrojového textu, ESI zbývající místo v cílovém bufferu, EDI ukazatel do cílového bufferu a EBP ukazatel lokálních proměnných v zásobníku. Lokální proměnné s kladným offsetem jsou použity jen pro čtení, jejich obsah není modifikován.

V zásobníku jsou vytvořeny lokální proměnné s následujícím významem. FORMVal je uschovaná zpětná hodnota pro funkci zpětného volání (uschovaný vstupní registr EAX). FORMNat je ukazatel na popisovač národnostních informací (uschovaný vstupní registr ECX). FORMCall je ukazatel na funkci zpětného volání (uschovaný vstupní registr EBP). FORMInx je aktuální index argumentu. FORMExpInx je explicitně zadaný index argumentu. FORMNum je střadač čteného čísla. FORMFlag jsou příznaky (podrobněji dále). FORMForm jsou formátovací parametry.

FORMFlag používají příznaky: FORMFLAG_NUM zahájeno načítání čísla, FORMFLAG_PREC zahájeno načítání přesnosti, FORMFLAG_EXP explicitní index argumentu je platný, FORMFLAG_INXW načíst šířku z argumentů, FORMFLAG_INXP načíst přesnost z argumentů, FORMFLAG_PAR načíst parametr *, FORMFLAG_PSET přesnost byla nastavena.


; ------------- Push registers

FormToTextBuf:	push	eax		; push EAX (callback value)
		push	ebx		; push EBX
		push	ecx		; push ECX (pointer to nationality)
		push	edx		; push EDX
		push	ebp		; push EBP (callback function)
		mov	ebp,esp		; EBP <- push ESP
		sub	esp,FORMStack	; ESP <- create local variables

; ------------- Prepare local variables

		mov	byte [FORMInx],0 ; clear current argument index
		mov	ecx,ebx		; ECX <- source text counter

Na začátku funkce jsou uchovány obsahy registrů (některé registry jsou použity jako lokální proměnné s kladným offsetem) a vytvořeno místo v zásobníku pro lokální proměnné. Aktuální index argumentu je vynulován a do registru ECX je připraven čítač znaků zdrojového textu.


; ------------- Check remaining free space in buffer

FormToTextBuf1:	or	esi,esi		; check remaining space
		jle	short FormToTextBuf8 ; not enough free space

; ------------- Read one character (-> AL)

FormToTextBuf2:	dec	ecx		; check next source character
		js	FormToTextBuf7	; end of source text
		mov	al,[edx]	; AL <- character from source text
		inc	edx		; increase source pointer

; ------------- Check if it is switch character

		cmp	al,"%"		; is it switch character?
		je	FormToTextBuf4	; switch character

; ------------- Store one character into destination buffer

FormToTextBuf3:	dec	esi		; decrease free space
		stosb			; store character into buffer
		jnz	FormToTextBuf2	; next character

; ------------- Pop registers

FormToTextBuf7:	clc			; clear error flag
FormToTextBuf8:	mov	esp,ebp		; pop ESP
		pop	ebp		; pop EBP
		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		pop	ebx		; pop EBX
		pop	eax		; pop EAX
		ret

Testem registru ESI je zkontrolováno zbývající volné místo v cílovém bufferu. Není-li místo pro další znak, funkce se ihned ukončí.

Čítáním registru ECX se zkontroluje, zda je připraven další zdrojový znak. Pokud ne, funkce se opět ihned ukončí. Jinak se ze zdrojového textu (ukazatel EDX) načte další znak.

Není-li dalším znakem znak procenta "%", který je použit jako indikátor začátku formátovací sekvence, znak se uloží do výstupního bufferu beze změny. Čítáním registru ESI se ověří zbývající místo v cílovém bufferu. Pokud dojde k zaplnění cílového bufferu, funkce se ihned ukončí.


; ------------- Prepare variables to read formatting parameters

FormToTextBuf4:	xor	ebx,ebx		; EBX <- 0, formatting parameters
		mov	[FORMFlagNum],bx ; clear read number and flags

; ------------- Read one character (-> AL)

FormToTextBuf5:	dec	ecx		; check next source character
		js	FormToTextBuf7	; end of source text
		mov	al,[edx]	; AL <- character from source text
		inc	edx		; increase source pointer

; ------------- Jump to character service

		cmp	al,32		; minimal character (space character)
		jb	FormToTextBuf3	; invalid character
		cmp	al,127		; maximal character
		jae	FormToTextBuf3	; invalid character
		movzx	eax,al		; EAX <- character
		jmp	[FormTextJumpTab+eax*4-32*4] ; jump

Je-li dalším znakem znak procenta "%", pokračuje se dále obsluhou zpracování formátovací sekvence. Registr EBX se vynuluje, bude použit jako střadač formátovacích parametrů.

Na začátku smyčky obsluhy znaků formátovací sekvence se čítáním registru ECX zkontroluje, zda je připraven další zdrojový znak. Pokud ne, funkce se ihned ukončí. Jinak se ze zdrojového textu (ukazatel EDX) načte další znak.

Ověří se platnost formátovacího znaku (musí ležet v intervalu 32 až 126) a provede se skok na osbluhu znaku podle tabulky FormTextJumpTab. Pro neplatný znak se obsluha formátovacího řetězce přeruší a znaky se opět začnou ukládat jako běžné znaky.


; ------------- Left-justify "-"

FormToTextLeft:	bts	ebx,FORMFLAG_Left_b ; set flag "left-justify"
		jmp	short FormToTextBuf5 ; next character

Obsluha znaku "-" nastaví v registru EBX příznak zarovnání textu vlevo.


; ------------- Always use sign "+"

FormToTextSign:	bts	ebx,FORMFLAG_Sign_b ; set flag "sign"
		jmp	short FormToTextBuf5 ; next character

Obsluha znaku "+" nastaví v registru EBX příznak vynuceného znaménka.


; ------------- Prefix space if number is positive " "

FormToTextSpace:bts	ebx,FORMFLAG_Spc_b ; set flag "space"
		jmp	short FormToTextBuf5 ; next character

Obsluha znaku mezery nastaví v registru EBX příznak náhrady kladného znaménka mezerou.


; ------------- Thousand separator "~"

FormToTextThsnd:bts	ebx,FORMFLAG_Thsn_b ; set flag "thousand"
		jmp	short FormToTextBuf5 ; next character

Obsluha znaku "~" nastaví v registru EBX příznak zobrazení oddělovačů řádů.


; ------------- Center "@"

FormToTextCent:	bts	ebx,FORMFLAG_Cent_b ; set flag "center"
		jmp	short FormToTextBuf5 ; next character

Obsluha znaku "@" nastaví v registru EBX příznak centrování textu.


; ------------- Alternate form "#" and "##"

FormToTextAlt:	btc	ebx,FORMFLAG_Alt_b ; alternate form
		jnc	short FormToTextBuf5 ; next character
		btc	ebx,FORMFLAG_Alt2_b ; flip alternate form 2
		jmp	short FormToTextBuf5 ; next character

Obsluha znaku "#" posune v registru EBX příznaky alternativního formátu. Příznaky FORMFLAG_Alt_b a FORMFLAG_Alt2_b se s příchodem znaků "#" postupně překlápí tak, že čítají znaky "#" v počtu 0, 1, 2 nebo 3.


; ------------- Precision "."

FormToTextPrec:	test	byte [FORMFlag],FORMFLAG_PREC ; precision?
		jnz	FormToTextPrec2	; precision has been started
		or	byte [FORMFlag],FORMFLAG_PREC ; start precision
		call	FormToTextStopW	; stop parsing width
		jmp	short FormToTextBuf5 ; next character

FormToTextPrec2:bts	ebx,FORMFLAG_Prec_b ; alternate precision
		jmp	short FormToTextBuf5 ; next character

Znak tečky "." je oddělovač pole přesnosti a pole šířky. Pokud v proměnné FORMFlag nebyl dosud nastaven přepínač FORMFLAG_PREC, nebylo zahájeno načítání přesnosti. Příznak se nastaví a voláním funkce FormToTextStopW se ukončí načítání pole šířky.

Byl-li příznak FORMFLAG_PREC nastaven, obsluha načítání přesnosti byla již zahájena. V tom případě se pouze nastavi příznak FORMFLAG_Prec_b indikující, že se použije alternativní přesnost "..".


; ------------- Integer size "I16", "I32", "I64"

FormToTextSize:	sub	ecx,byte 2	; check number of characters
		js	short FormToTextBuf7 ; end of source text
		mov	ax,[edx]	; AX <- get 2 characters
		inc	edx		; increase pointer
		inc	edx		; increase pointer
		cmp	ax,"64"		; long variant?
		je	short FormToTextLong ; long variant
		cmp	ax,"16"		; short variant?
		je	short FormToTextShrt ; short variant
		cmp	ax,"32"		; default variant?
		jne	FormToTextSize2	; no default variant
		btr	ebx,FORMFLAG_Long_b ; reset flag "long"
		btr	ebx,FORMFLAG_Shrt_b ; reset flag "short"
FormToTextBuf52:jmp	short FormToTextBuf5 ; next character

FormToTextSize2:inc	ecx		; increase number of characters
		dec	edx		; decrease pointer
		inc	ecx		; increase number of characters
		dec	edx		; decrease pointer
		jmp	short FormToTextBuf52 ; next character

Znak velkého písmene "I" označuje přepínač nastavení velikosti argumentu. Platné přepínače mají tvar "I16", "I32" a "I64", proto je kontrolou registru ECX ověřeno, zda zbývají 2 znaky zdrojového textu a pokud zbývají, jsou další 2 znaky načteny do registru AX.

Jedná-li se o text "I64", je pokračováno obsluhou dlouhé varianty argumentu. Jedná-li se o text "I16", pokračuje se obsluhou krátké varianty argumentu. V případě textu "I32" se pokračuje obsluhou střední varianty argumentu. Obsluha spočívá ve vynulování příznaků krátké a dlouhé varianty argumentu.

V ostatních případech se ukazatel zdrojového textu navrátí za pozici znaku "I" a pokračuje se obsluhou dalších znaků.


; ------------- Digit "0" to "9"

FormToTextDig0:	test	byte [FORMFlag],FORMFLAG_NUM+FORMFLAG_PREC ; first 0?
		jz	short FormToTextZero ; first zero digit
FormToTextDig:	or	byte [FORMFlag],FORMFLAG_NUM ; start number
		mov	ah,[FORMNum]	; AH <- number
		sub	al,"0"		; AL <- digit
		cmp	ah,25		; check overflow
		jae	FormToTextDig4	; it will overflow or maybe it will not
		aad			; AL <- AL + AH*10
FormToTextDig2:	mov	[FORMNum],al	; store new number
		jmp	short FormToTextBuf52 ; next character

FormToTextDig4:	ja	FormToTextDig6	; it will overflow
		aad			; AL <- AL + AH*10
		cmp	al,250		; check overflow
		jae	FormToTextDig2	; parameter is OK
FormToTextDig6:	mov	al,255		; AL <- limit on overflow
		jmp	short FormToTextDig2 ; next character

; ------------- Add zeros instead of spaces "0"

FormToTextZero:	bts	ebx,FORMFLAG_Zero_b ; set flag "zero"
		jmp	short FormToTextBuf52 ; next character

Číslice "0" se může vyskytnout jen uvnitř čísla. Pokud načítání čísla ještě nebylo zahájeno a ani nebylo zahájeno pole přesnosti, je číslice "0" považována za příznak, nastaví se příznak požadavku doplnění nul před číslo.

Jedná-li se o číslici "1" až "9" nebo o platnou číslici "0", bude provedena obsluha načítání čísla. Nastaví se příznak FORMFLAG_NUM indikující, že bylo zahájeno číslo. Do registru AH je připraven střadač čísla FORMNum. Má-li střadač hodnotu menší než 25, nedojde určitě k přetečení čísla rozměru BYTE a nová číslice je přidána ke střadači instrukcí AAD.

Je-li střadač větší než 25, k přetečení dojde a číslo je omezeno na maximální povolenou hodnotu 255. Je-li střadač roven 25, k přetečení může nebo nemusí dojít. Nová číslice se přidá ke střadači a pokud je nová hodnota střadače menší než 250, došlo k přetečení a číslo je opět omezeno na 255.


; ------------- Get parameter "*"

FormToTextArg:	or	byte [FORMFlag],FORMFLAG_PAR ; set flag "parameter"
		jmp	short FormToTextBuf52 ; next character

Obsluha znaku "*" nastaví v registru EBX příznak, že číselný parametr (šířka nebo přesnost) bude načten z argumentu.


; ------------- Long variant "l", "L"

FormToTextLong:	bts	ebx,FORMFLAG_Long_b ; set flag "long"
		btr	ebx,FORMFLAG_Shrt_b ; reset flag "short"
		jmp	short FormToTextBuf52 ; next character

Obsluha znaku "l" nebo "L" zapne v registru EBX příznak dlouhého argumentu a vypne příznak krátkého argumentu.


; ------------- Short variant "h", "H"

FormToTextShrt:	btr	ebx,FORMFLAG_Long_b ; reset flag "long"
		bts	ebx,FORMFLAG_Shrt_b ; set flag "short"
		jmp	short FormToTextBuf52 ; next character

Obsluha znaku "h" nebo "H" vypne v registru EBX příznak dlouhého argumentu a zapne příznak krátkého argumentu.


; ------------- Indexed argument "$"

FormToTextInx:	mov	al,0		; AL <- 0
		xchg	al,[FORMNum]	; AL <- number, clear number
		and	byte [FORMFlag],~FORMFLAG_NUM ; stop number
		or	al,al		; is index valid?
		jz	FormToTextBuf54	; index is not valid
		dec	eax		; AL <- correct index value
		test	byte [FORMFlag],FORMFLAG_PAR ; get "parameter"?
		jnz	FormToTextInx2	; yes, parameter is valid
		mov	[FORMExpInx],al	; store explicit argument index
		or	byte [FORMFlag],FORMFLAG_EXP ; explicit argument valid
FormToTextBuf54:jmp	short FormToTextBuf52 ; next character

FormToTextInx2:	and	byte [FORMFlag],~FORMFLAG_PAR ; clear "parameter"
		test	byte [FORMFlag],FORMFLAG_PREC ; precision?
		jnz	FormToTextInx4	; precision has been started
		mov	bh,al		; store width index
		or	byte [FORMFlag],FORMFLAG_INXW ; width from arguments
		jmp	short FormToTextBuf54 ; next character

FormToTextInx4:	mov	bl,al		; store precision index
		or	byte [FORMFlag],(FORMFLAG_INXP+FORMFLAG_PSET)
		jmp	short FormToTextBuf54 ; next character

Znak "$" označuje explicitní index argumentu. Do registru AL je připraven střadač číselného parametru a střadač je vynulován (spolu s příznakem zahájení číselného argumentu). Index s hodnotou 0 není platný a ignoruje se. Pro hodnotu 1 a více se index dekrementací převede na bázi 0.

Pokud nebyl nastaven příznak "*" načítání číselného parametru z argumentu FORMFLAG_PAR, má index význam explicitního indexu argumentu. Index se uloží do proměnné FORMExpInx a nastaví se příznak FORMFLAG_EXP.

Pokud byl příznak "*" nastaven, bude z argumentu načten parametr šířky nebo přesnosti. Příznak FORMFLAG_PAR se vynuluje a testem příznaku FORMFLAG_PREC se rozliší, zda je načítán parametr šířky nebo přesnosti a podle výsledku se index uloží do registrů BH nebo BL a nastaví se příznaky FORMFLAG_INXW nebo FORMFLAG_INXP+FORMFLAG_PSET.


; ------------- Signed decimal int "d", "D", "i"

FormToTextDC:	bts	ebx,FORMTYPE_Cap_b ; set flag "capital"
FormToTextDS:
FormToTextIS:	or	ebx,(FORMTYPE_Int<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr2 ; invalid argument index
		jnz	FormToTextDS2	; no default precision
		mov	bl,1		; BL <- 1, default precision
FormToTextDS2:	push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	IntToTextBuf	; convert signed INT into buffer
		pop	ecx		; pop ECX
		pop	edx		; pop EDX
		jmp	short FormToTextOK2 ; read next character

Znaky "d", "D" a "i" jsou indikátory celého dekadického čísla se znaménkem. Pro znak "D" se nastaví příznak velkého písmene a dále se pokračuje společnou obsluhou.

Do registru EBX se uloží příznak celočíselného dekadického čísla se znaménkem FORMTYPE_Int. Voláním funkce FormToTextGet se do registrového páru EDX:EAX načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 1. Voláním funkce IntToTextBuf se číslo zformátuje do výstupního bufferu.


; ------------- Unsigned decimal int "u", "U"

FormToTextUC:	bts	ebx,FORMTYPE_Cap_b ; set flag "capital"
FormToTextUS:	or	ebx,(FORMTYPE_UInt<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr2 ; invalid argument index
		jnz	FormToTextUS2	; no default precision
		mov	bl,1		; BL <- 1, default precision
FormToTextUS2:	push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	UIntToTextBuf	; convert unsigned INT into buffer
		pop	ecx		; pop ECX
		clc
FormToTextErr2:	pop	edx		; pop EDX
		jc	FormToTextBuf8	; invalid argument index
FormToTextOK2:	jmp	FormToTextBuf1	; read next character

Znaky "u" a "U" jsou indikátory celého dekadického čísla bez znaménka. Pro znak "U" se nastaví příznak velkého písmene a dále se pokračuje společnou obsluhou.

Do registru EBX se uloží příznak celočíselného dekadického čísla bez znaménka FORMTYPE_UInt. Voláním funkce FormToTextGet se do registrového páru EDX:EAX načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 1. Voláním funkce UIntToTextBuf se číslo zformátuje do výstupního bufferu.


; ------------- Unsigned binary int "b", "B"

FormToTextBC:	bts	ebx,FORMTYPE_Cap_b ; set flag "capital"
FormToTextBS:	or	ebx,(FORMTYPE_Bin<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr2 ; invalid argument index
		jnz	FormToTextBS2	; no default precision
		mov	bl,1		; BL <- 1, default precision
FormToTextBS2:	push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	BinToTextBuf	; convert BIN number into buffer
		pop	ecx		; pop ECX
		pop	edx		; pop EDX
		jmp	short FormToTextOK2 ; read next character

Znaky "b" a "B" jsou indikátory celého binárního čísla bez znaménka. Pro znak "B" se nastaví příznak velkého písmene a dále se pokračuje společnou obsluhou.

Do registru EBX se uloží příznak celočíselného binárního čísla bez znaménka FORMTYPE_Bin. Voláním funkce FormToTextGet se do registrového páru EDX:EAX načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 1. Voláním funkce BinToTextBuf se číslo zformátuje do výstupního bufferu.


; ------------- Unsigned octal int "o", "O"

FormToTextOC:	bts	ebx,FORMTYPE_Cap_b ; set flag "capital"
FormToTextOS:	or	ebx,(FORMTYPE_Oct<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr2 ; invalid argument index
		jnz	FormToTextOS2	; no default precision
		mov	bl,1		; BL <- 1, default precision
FormToTextOS2:	call	OctToTextBuf	; convert OCT number into buffer
		pop	edx		; op EDX
		jmp	short FormToTextOK2 ; read next character

Znaky "o" a "O" jsou indikátory celého oktalového čísla bez znaménka. Pro znak "O" se nastaví příznak velkého písmene a dále se pokračuje společnou obsluhou.

Do registru EBX se uloží příznak celočíselného oktalového čísla bez znaménka FORMTYPE_Oct. Voláním funkce FormToTextGet se do registrového páru EDX:EAX načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 1. Voláním funkce OctToTextBuf se číslo zformátuje do výstupního bufferu.


; ------------- Unsigned hex int "x"

FormToTextXS:	or	ebx,(FORMTYPE_Hex<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr2 ; invalid argument index
		jnz	FormToTextXS2	; no default precision
		mov	bl,1		; BL <- 1, default precision
FormToTextXS2:	push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	HexSToTextBuf	; convert HEX small into buffer
		pop	ecx		; pop ECX
		pop	edx		; pop EDX
		jmp	short FormToTextOK ; read next character

Znak "x" je indikátor celého hexadecimálního čísla bez znaménka s malými písmeny "a" až "f".

Do registru EBX se uloží příznak celočíselného hexadecimálního čísla bez znaménka FORMTYPE_Hex. Voláním funkce FormToTextGet se do registrového páru EDX:EAX načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 1. Voláním funkce HexSToTextBuf se číslo zformátuje do výstupního bufferu (s použitím malých písmen "a" až "f").


; ------------- Unsigned hex int "X"

FormToTextXC:	or	ebx,((FORMTYPE_Hex+FORMTYPE_Cap)<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr ; invalid argument index
		jnz	FormToTextXC2	; no default precision
		mov	bl,1		; BL <- 1, default precision
FormToTextXC2:	push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	HexCToTextBuf	; convert HEX capital into buffer
		pop	ecx		; pop ECX
		pop	edx		; pop EDX
		jmp	short FormToTextOK ; read next character

Znak "X" je indikátor celého hexadecimálního čísla bez znaménka s velkými písmeny "A" až "F".

Do registru EBX se uloží příznak celočíselného hexadecimálního čísla bez znaménka FORMTYPE_Hex a příznak velkého písmene FORMTYPE_Cap. Voláním funkce FormToTextGet se do registrového páru EDX:EAX načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 1. Voláním funkce HexCToTextBuf se číslo zformátuje do výstupního bufferu (s použitím velkých písmen "A" až "F").


; ------------- Character "C", "c"

FormToTextCC:	bts	ebx,FORMTYPE_Cap_b ; set flag "capital"
FormToTextCS:	or	ebx,(FORMTYPE_Char<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr ; invalid argument index
		pop	edx		; pop EDX
		xchg	ebp,esi		; EBP <- remaining space
		call	CharUTF8Write	; store character into buffer
		xchg	ebp,esi		; ESI <- remaining space
		jmp	short FormToTextOK ; read next character

Znaky "c" a "C" jsou indikátory jednoho znaku v Unicode kódu. Pro znak "C" se nastaví příznak velkého písmene a dále se pokračuje společnou obsluhou.

Do registru EBX se uloží příznak znaku Unicode FORMTYPE_Char. Voláním funkce FormToTextGet se do registru EAX načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Voláním funkce CharUTF8Write se znak uloží do výstupního bufferu v kódu UTF-8.


; ------------- String "S", "s"

FormToTextSC:	bts	ebx,FORMTYPE_Cap_b ; set flag "capital"
FormToTextSS:	or	ebx,(FORMTYPE_String<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr ; invalid argument index
		call	FormToTextLim	; limit text length by precision
		push	ecx		; push ECX
		mov	ecx,edx		; ECX <- length of text
		cmp	ecx,esi		; check remaining space
		jl	FormToTextSS2	; text length is OK
		mov	ecx,esi		; ECX <- limit text length
FormToTextSS2:	sub	esi,ecx		; ESI <- new remaining text
		push	esi		; push ESI
		xchg	eax,esi		; ESI <- pointer to text
		mov	eax,ecx		; EAX <- text length
		shr	ecx,2		; ECX <- text length in DWORDs
		rep	movsd		; copy text in DWORDs
		and	eax,byte 3	; EAX <- size in last DWORD
		xchg	eax,ecx		; ECX <- size in last DWORD
		rep	movsb		; copy rest of text
		pop	esi		; pop ESI
		pop	ecx		; pop ECX (here is NC)
FormToTextErr:	pop	edx		; pop EDX
		jc	FormToTextBuf8	; invalid argument index
FormToTextOK:	jmp	FormToTextBuf1	; read next character

Znaky "s" a "S" jsou indikátory textu v kódu UTF-8. Pro znak "S" se nastaví příznak velkého písmene a dále se pokračuje společnou obsluhou.

Do registru EBX se uloží příznak textu FORMTYPE_String. Voláním funkce FormToTextGet se do registru EAX načte ukazatel na text v kódu UTF-8 a do registru EDX délka textu v bajtech. V případě neplatného indexu argumentu se funkce ukončí s chybou.

Voláním funkce FormToTextLim se délka omezí podle zadaného argumentu přesnosti a následně se délka omezí volným místem v cílovém bufferu.

Text se zkopíruje do výstupního bufferu. Nejdříve rychlá kopie po čtyřslovech a poté kopie zbytku textu po jednotlivých bajtech.


; ------------- Floating point "f", "F"

FormToTextFC:	bts	ebx,FORMTYPE_Cap_b ; set flag "capital"
FormToTextFS:	or	ebx,(FORMTYPE_Float<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr ; invalid argument index
		jnz	FormToTextFS2	; no default precision
		mov	bl,6		; BL <- 6, default precision
FormToTextFS2:	pop	edx		; pop EDX
		push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	FltToTextBuf	; convert float number into buffer
		pop	ecx		; pop ECX
		ffreep	st0		; free number from FPU stack
		jmp	short FormToTextOK ; read next character

Znaky "f" a "F" jsou indikátory desetinného čísla bez exponentu. Pro znak "F" se nastaví příznak velkého písmene a dále se pokračuje společnou obsluhou.

Do registru EBX se uloží příznak desetinného čísla bez exponentu FORMTYPE_Float. Voláním funkce FormToTextGet se do registru ST0 načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 6. Voláním funkce FltToTextBuf se číslo zformátuje do výstupního bufferu. Po návratu z funkce se číslo uvolní ze zásobníku koprocesoru instrukcí ffreep.


; ------------- Exponential "e"

FormToTextES:	or	ebx,(FORMTYPE_Exp<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr ; invalid argument index
		jnz	FormToTextES2	; no default precision
		mov	bl,6		; BL <- 6, default precision
FormToTextES2:	pop	edx		; pop EDX
		push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	ExpSToTextBuf	; convert exponent small into buffer
		pop	ecx		; pop ECX
		ffreep	st0		; free number from FPU stack
		jmp	short FormToTextOK ; read next character

Znak "e" je indikátor desetinného čísla s exponentem s malým "e" použitým jako oddělovač exponentu.

Do registru EBX se uloží příznak desetinného čísla s exponentem FORMTYPE_Exp. Voláním funkce FormToTextGet se do registru ST0 načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 6. Voláním funkce ExpSToTextBuf se číslo zformátuje do výstupního bufferu s použitím malého písmene "e" jako oddělovač exponentu. Po návratu z funkce se číslo uvolní ze zásobníku koprocesoru instrukcí ffreep.


; ------------- Exponential "E"

FormToTextEC:	or	ebx,((FORMTYPE_Exp+FORMTYPE_Cap)<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
FormToTextErr3:	jc	short FormToTextErr ; invalid argument index
		jnz	FormToTextEC2	; no default precision
		mov	bl,6		; BL <- 6, default precision
FormToTextEC2:	pop	edx		; pop EDX
		push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	ExpCToTextBuf	; convert exponent capital into buffer
		pop	ecx		; pop ECX
		ffreep	st0		; free number from FPU stack
		jmp	short FormToTextOK ; read next character

Znak "E" je indikátor desetinného čísla s exponentem s velkým "E" použitým jako oddělovač exponentu.

Do registru EBX se uloží příznak desetinného čísla s exponentem FORMTYPE_Exp a příznak velkého písmene FORMTYPE_Cap. Voláním funkce FormToTextGet se do registru ST0 načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 6. Voláním funkce ExpCToTextBuf se číslo zformátuje do výstupního bufferu s použitím velkého písmene "E" jako oddělovač exponentu. Po návratu z funkce se číslo uvolní ze zásobníku koprocesoru instrukcí ffreep.


; ------------- Mixed "g"

FormToTextGS:	or	ebx,(FORMTYPE_Mix<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr3 ; invalid argument index
		jnz	FormToTextGS2	; no default precision
		mov	bl,6		; BL <- 6, default precision
FormToTextGS2:	pop	edx		; pop EDX
		push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	MixSToTextBuf	; convert mixed small into buffer
		pop	ecx		; pop ECX
		ffreep	st0		; free number from FPU stack
		jmp	short FormToTextOK3 ; read next character

Znak "g" je indikátor desetinného čísla ve smíšeném tvaru s malým "e" použitým jako oddělovač exponentu.

Do registru EBX se uloží příznak desetinného čísla ve smíšeném tvaru FORMTYPE_Mix. Voláním funkce FormToTextGet se do registru ST0 načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 6. Voláním funkce MixSToTextBuf se číslo zformátuje do výstupního bufferu s použitím malého písmene "e" jako oddělovač exponentu. Po návratu z funkce se číslo uvolní ze zásobníku koprocesoru instrukcí ffreep.


; ------------- Mixed "G"

FormToTextGC:	or	ebx,((FORMTYPE_Mix+FORMTYPE_Cap)<<FORMPAR_TypeF_b)
		push	edx		; push EDX
		call	FormToTextGet	; get parameters
		jc	short FormToTextErr3 ; invalid argument index
		jnz	FormToTextGC2	; no default precision
		mov	bl,6		; BL <- 6, default precision
FormToTextGC2:	pop	edx		; pop EDX
		push	ecx		; push ECX
		mov	ecx,[FORMNat]	; ECX <- pointer to nationality
		call	MixCToTextBuf	; convert mixed capital into buffer
		pop	ecx		; pop ECX
		ffreep	st0		; free number from FPU stack
FormToTextOK3:	jmp	FormToTextBuf1	; read next character

Znak "G" je indikátor desetinného čísla ve smíšeném tvaru s velkým "E" použitým jako oddělovač exponentu.

Do registru EBX se uloží příznak desetinného čísla ve smíšeném tvaru FORMTYPE_Mix a příznak velkého písmene FORMTYPE_Cap. Voláním funkce FormToTextGet se do registru ST0 načte hodnota argumentu. V případě neplatného indexu argumentu se funkce ukončí s chybou. Pokud nebyla zadána přesnost, nastaví se do registru BL implicitní přesnost 6. Voláním funkce MixCToTextBuf se číslo zformátuje do výstupního bufferu s použitím velkého písmene "E" jako oddělovač exponentu. Po návratu z funkce se číslo uvolní ze zásobníku koprocesoru instrukcí ffreep.


; -----------------------------------------------------------------------------
;           Local function - limit text length by precision parameter
; -----------------------------------------------------------------------------

FormToTextLim:	or	bl,bl		; limit text length?
		jz	FormToTextLim9	; length not limited

		push	ecx		; push ECX
		push	esi		; push ESI
		push	eax		; push EAX (start of text)

		mov	ecx,edx		; ECX <- text length
		xchg	eax,esi		; ESI <- source text

FormToTextLim2:	jecxz	FormToTextLim4	; no characters remain
		call	CharUTF8Read	; read one character
		dec	bl		; character counter
		jnz	FormToTextLim2	; get next character

FormToTextLim4:	mov	edx,esi		; EDX <- end of text
		pop	eax		; pop EAX (start of text)
		sub	edx,eax		; EDX <- new text length
		pop	esi		; pop ESI
		pop	ecx		; pop ECX

FormToTextLim9:	ret

FormToTextLim je interní funkce pro funkce FormToTextBuf a FormToTextBufN. Funkce omezí délku textu argumentu "s" a "S" podle parametru přesnosti.

Je-li požadovaná přesnost v registru BL rovna nule, délka textu nebude omezena a funkce se ihned ukončí.

Není-li přesnost v registru BL nulová, představuje maximální počet znaků, které mají být uloženy do výstupního bufferu. Vzhledem k použití kódu s nestejnou délkou znaků UTF-8 je nutné zjistit délku textu v bajtech.

Ze vstupního bufferu se voláním funkce CharUTF8Read postupně načítají jednotlivé znaky textu a to buď do dosažení konce zdrojového textu nebo do načtení BL znaků. Po nalezení konce textu se z rozdílu zdrojové adresy zjistí délka textu v bajtech.


; -----------------------------------------------------------------------------
;                     Local function - stop parsing width
; -----------------------------------------------------------------------------

FormToTextStopW:mov	al,0		; AL <- 0
		xchg	al,[FORMNum]	; AL <- number, clear number
		test	byte [FORMFlag],FORMFLAG_INXW ; width from arguments?
		jnz	FormToTextStpW4	; width is already set
		mov	bh,al		; store width (or index)
		test	byte [FORMFlag],FORMFLAG_PAR ; get parameter?
		jz	short FormToTextStpW4 ; no
		mov	bh,[FORMInx]	; BH <- current argument index
		inc	byte [FORMInx]	; increase argument index
		or	byte [FORMFlag],FORMFLAG_INXW ; width from arguments
FormToTextStpW4:and	byte [FORMFlag],~(FORMFLAG_PAR+FORMFLAG_NUM); clr flags
		ret

FormToTextStopW je interní funkce pro funkce FormToTextBuf a FormToTextBufN. Funkce ukončí rozbor parametru šířky.

Na začátku se do registru AL načte obsah střadače čísla FORMNum a střadač se vynuluje. Je-li nastaven příznak FORMFLAG_INXW, bude údaj šířky načten z argumentu s explicitním indexem a registr BH již obsahuje index argumentu, funkce se ukončí.

Nejedná-li se o načtení parametru z argumentu, je úda šířky uložen do registru BH jako nově zadaná šířka. Není-li nastaven příznak FORMFLAG_PAR (přepínač "*"), je načtené číslo přímo údajem šířky a funkce může být ukončena.

Je-li příznak FORMFLAG_PAR nastaven, bude se parametr načítat z argumentů. Do registru BH se připraví index dalšího argumentu FORMInx, index se inkrementuje a nastaví se příznak FORMFLAG_INXW požadující načtení parametru z argumentu.

Na závěr funkce se vynulují příznaky FORMFLAG_PAR (požadavek k načtení parametru z argumentů) a FORMFLAG_NUM (příznak zahájení čísla).


; -----------------------------------------------------------------------------
;                  Local function - stop parsing precision
; -----------------------------------------------------------------------------

FormToTextStopP:test	byte [FORMFlag],FORMFLAG_INXP ; prec. from arguments?
		jnz	FormToTextStpP4	; precision is already set
		test	byte [FORMFlag],FORMFLAG_NUM ; number entered?
		jz	FormToTextStpP2	; not valid
		mov	bl,[FORMNum]	; store precision (or index)
		or	byte [FORMFlag],FORMFLAG_PSET ; precision has been set
FormToTextStpP2:test	byte [FORMFlag],FORMFLAG_PAR ; get parameter?
		jz	short FormToTextStpP4 ; no
		mov	bl,[FORMInx]	; BL <- current argument index
		inc	byte [FORMInx]	; increase argument index
		or	byte [FORMFlag],(FORMFLAG_INXP+FORMFLAG_PSET)
FormToTextStpP4:ret

FormToTextStopP je interní funkce pro funkci FormToTextGet. Funkce ukončí rozbor parametru přesnosti.

Je-li nastaven příznak FORMFLAG_INXP, bude údaj přesnosti načten z argumentu s explicitním indexem (index je již obsažen v registru BL), funkce se ihned ukončí.

Nejedná-li se o načtení parametru z argumentu, je údaj FORMNum načten do registru BL jako nově zadaná přesnost a nastaví se příznak FORMFLAG_PSET indikující, že byla zadána přesnost.

Není-li nastaven příznak FORMFLAG_PAR (přepínač "*"), je načtené číslo přímo údajem přesnosti a funkce může být ukončena.

Je-li příznak FORMFLAG_PAR nastaven, bude se parametr načítat z argumentů. Do registru BL se připraví index dalšího argumentu FORMInx, index se inkrementuje a nastaví se příznak FORMFLAG_INXP (požadující načtení parametru z argumentu) a příznak FORMFLAG_PSET (indikující, že byla zadána přesnost).


; -----------------------------------------------------------------------------
;            Local function - get parameters (output EAX, EDX, ST0)
; -----------------------------------------------------------------------------
; Output: CY=invalid argument index, NZ(and NC)=no default precision

; ------------- Push registers

FormToTextGet:	push	ecx		; push ECX

; ------------- Stop parsing

		test	byte [FORMFlag],FORMFLAG_PREC ; precision?
		jnz	FormToTextGet2	; precision has been started
		call	FormToTextStopW	; stop parsing width
		jmp	short FormToTextGet4
FormToTextGet2:	call	FormToTextStopP	; stop parsing precision

FormToTextGet je interní funkce pro funkce FormToTextBuf a FormToTextBufN. Funkce načte jeden argument. Argument je navrácen v registrech EAX, EDX nebo ST0. Navrácený příznak CY indikuje neplatný index argumentu. Příznak NZ indikuje, že nemá být implicitní přesnost.

Funkce nejdříve ukončí právě prováděný rozbor. Podle nastavení příznaku FORMFLAG_PREC ukončí zavoláním funkce FormToTextStopW rozbor šířky nebo zavoláním funkce FormToTextStopP rozbor přesnosti.


; ------------- Prepare width

FormToTextGet4:	test	byte [FORMFlag],FORMFLAG_INXW ; width from arguments?
		jz	FormToTextGet5	; no width from arguments
		push	ebx		; push EBX
		movzx	edx,bh		; EDX <- argument index
		and	ebx,~(FORMTYPE_Mask<<FORMPAR_TypeF_b) ; clear arg. type
		mov	eax,[FORMVal]	; EAX <- callback value
		call	dword [FORMCall] ; get argument
		pop	ebx		; pop EBX
		jc	short FormToTextGet9 ; invalid argument index
		mov	bh,255		; limit width
		cmp	eax,255		; check maximal width
		ja	FormToTextGet5	; overflow
		mov	bh,al		; BH <- width from argument

Je-li nastaven příznak FORMFLAG_INXW, bude se parametr šířky načítat z argumentů. Do registru EDX se připraví z registru BH index argumentu parametru šířky. Přechodně se vynuluje typ argumentu a tím se nastaví typ FORMTYPE_Par (hardcoded 0).

Zavoláním funkce FORMCall se zpětnou hodnotou FORMVal se z argumentů načte parametr šířky. V případě neplatného indexu argumentu (je navrácen příznak CY) se funkce ihned ukončí. Navrácený argument se omezí na hodnotu 255 a uloží do registru BH.


; ------------- Prepare precision

FormToTextGet5:	test	byte [FORMFlag],FORMFLAG_INXP ; prec. from arguments?
		jz	FormToTextGet6	; no precision from arguments
		push	ebx		; push EBX
		movzx	edx,bl		; EDX <- argument index
		and	ebx,~(FORMTYPE_Mask<<FORMPAR_TypeF_b) ; clear arg. type
		mov	eax,[FORMVal]	; EAX <- callback value
		call	dword [FORMCall] ; get argument
		pop	ebx		; pop EBX
		jc	short FormToTextGet9 ; invalid argument index
		mov	bl,255		; limit precision
		cmp	eax,255		; check maximal precision
		ja	FormToTextGet6	; overflow
		mov	bl,al		; BL <- precision from argument

Je-li nastaven příznak FORMFLAG_INXP, bude se parametr přesnosti načítat z argumentů. Do registru EDX se připraví z registru BL index argumentu parametru přesnosti. Přechodně se vynuluje typ argumentu a tím se nastaví typ FORMTYPE_Par (hardcoded 0).

Zavoláním funkce FORMCall se zpětnou hodnotou FORMVal se z argumentů načte parametr přesnosti. V případě neplatného indexu argumentu (je navrácen příznak CY) se funkce ihned ukončí. Navrácený argument se omezí na hodnotu 255 a uloží do registru BL.


; ------------- Prepare argument index

FormToTextGet6:	movzx	edx,byte [FORMExpInx] ; EDX <- explicit argument index
		test	byte [FORMFlag],FORMFLAG_EXP ; explicit argument?
		jnz	FormToTextGet7	; yes, use explicit argument
		movzx	edx,byte [FORMInx] ; EDX <- current argument index
		call	FormGetArgLen	; get argument length (-> EAX)
		add	[FORMInx],al	; increase argument index

Je-li nastaven příznak FORMFLAG_EXP, je index argumentu načten z FORMExpInx. Není-li nastaven, je použit implicitní aargument z FORMInx. Pomocí funkce FormGetArgLen je zjištěna délka argumentu a posunut index argumentu FORMInx.


; ------------- Get argument

FormToTextGet7:	mov	eax,[FORMVal]	; EAX <- callback value
		push	ebx		; push EBX
		call	dword [FORMCall] ; get argument
		pop	ebx		; pop EBX
		jc	short FormToTextGet9 ; invalid argument index
		test	byte [FORMFlag],FORMFLAG_PSET ; no default precision?

; ------------- Pop registers

FormToTextGet9: pop	ecx		; pop ECX
		ret

Nyní je již může načíst hodnota argumentu. Do registru EAX se připraví zpětná hodnota a voláním funkce FORMCall se z argumentů načte argument s indexem EDX. Je-li navrácen příznak chyby indexu argumentu CY, funkce se ihned ukončí. Testem příznaku FORMFLAG_PSET je nastaven příznak ZF indikující, zda byl nastaven parametr přesnosti.


Obsah / Utility / TEXTFORM / FormToTextBuf