Page 3 of 5
Re: Format string with some values like sprintf (C) - Update
Posted: Sat May 02, 2015 10:21 am
by mk-soft
Thanks for answers,
No Bug, because the parameter is from type Word (uVal) but %8X read type Long.
Code: Select all
IncludeFile "Format-v207.pbi"
aVal.a = $FF
uVal.u = $E0E0
lVal.l = $AAAAAAAA
qVal.q = $00EE00EE00EE00EE
temp.s = "Result:\n"
temp + "Hex2 = %2X\nHex4 = %4X\nHex8 = %8X\nHex16 = %16X\n\n"
temp + "Invalid read Hex8 on uVal = %8x"
result.s = format(temp, @aVal, @uVal, @lVal, @qVal, @uVal)
MessageRequester("Format like sprintf", result)
Re: Format string with some values like sprintf (C) - Update
Posted: Sun Feb 05, 2017 1:51 pm
by mk-soft
Update v2.08
- Removed null character '\0' (It does not work)
Example
Code: Select all
IncludeFile "Format.pbi"
bVal.b = 100
wVal.w = 200
lVal.l = 300
iVal.i = 400
fVal.f = 500.0
dVal.d = -600.0
sVal.s = "Hello World"
aVal.a = 255
uVal.u = 65535
temp.s = "Result: \nByte = %b, \nWord = %w, \nLong = %l, \nInteger = %i, \nFloat = %10.2f, \nDouble = %-+10.2d, \n"
temp + "String = %s, \nUnsigned Byte = %a, \nUnsigned Word = %u,\n"
temp + "Hex = %2x, \nHex = %4X"
result.s = format(temp, @bVal, @wVal, @lVal, @iVal, @fVal, @dVal, @sVal, @aVal, @uVal, @aVal, @uVal)
MessageRequester("Format like sprintf", result)
Re: Format string with some values like sprintf (C) - Update
Posted: Tue Dec 12, 2017 5:30 am
by pthien
Sorry to resurrect an old post.
But I'm trying to use this format function to help make my SQL commands.
But I cannot do a format("Test number %s",str(x)) because the format function wants me to pass by reference and I don't know how to pass the results of a function like Str() as a reference.
I can make an intermediate variable and it works:
number.s = str(x)
format("Test number %s",@number)
But I'd like to skip the extra steps.
Any ideas?
Also, is this format function still the way to go? When I compile I get a "Deprecated Str(Q)" message.
Thanks for all the help!
Re: Format string with some values like sprintf (C) - Update
Posted: Tue Dec 12, 2017 4:52 pm
by mk-soft
It´s only work with pointer to variable, but you don´t need Str(Number).
Code: Select all
Define number.q = 12345678
r1.s = format("Test quat number %q", @number)
Debug r1
SQL
Code: Select all
myTable$ = "Data1"
myNumber.q = 12345678
query$ = format("SELECT * FROM %s WHERE MyValue >= %q", @myTable$, @myNumber)
Debug query$
Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 8:16 pm
by luis
Did anyone ever tried this on x64 Linux ?
This test
Code: Select all
v1 = 1
v2 = 2
v3 = 3
v4 = 4
v5 = 5
v6 = 6
v7 = 7
v8 = 8
v9 = 9
v10 = 10
v11 = 11
t$ = Format("test %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i", @v1, @v2, @v3, @v4, @v5, @v6, @v7, @v8, @v9, @v10, @v11)
Debug t$
crashes for me with IMA on
Code: Select all
Case 'i'
If *value : help = Str ( *value\i ) : EndIf : IsValue = #True
Tested with PB5.62 on Linux Mint x64
Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 8:22 pm
by luis
I saw the code assumes it can move on the next parameter by adding the size of an integer to the pointer to the first parameter.
It works for the first param but crashes for the second.
OK, I looked at the stack, it seems the parameters on x64 Linux are 16 bits aligned and so are separated by 8 bytes.
In fact, if I change the line
to
Code: Select all
*args + SizeOf ( Integer ) * 2
Break
the code works again.
Is this actually how it is supposed to be ? On x64 Windows the params are on the stack simply one after another.
UPDATE:
Maybe I found it. Looks like it's the Purifier.
Yes, it really looks like it's that. With the Purifier enabled the offset becomes 16 bytes instead of 8, but ONLY under Linux x64, everywhere else does not have any effect (?).
This is a problem because I can't enable the Purifier if the source is using this code. Maybe it's possible to disable it around the procedure, but I'm not crazy about it.
Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 10:25 pm
by idle
you could also try import a c function, if you get stuck, but it's not the same
Code: Select all
;d Or i Signed decimal integer 392
;u Unsigned decimal integer 7235
;o Unsigned octal 610
;x Unsigned hexadecimal integer 7fa
;X Unsigned hexadecimal integer (uppercase) 7FA
;f Decimal floating point, lowercase 392.65
;F Decimal floating point, uppercase 392.65
;e Scientific notation (mantissa/exponent), lowercase 3.9265e+2
;E Scientific notation (mantissa/exponent), uppercase 3.9265E+2
;g Use the shortest representation: %e Or %f 392.65
;G Use the shortest representation: %E Or %F 392.65
;a Hexadecimal floating point, lowercase -0xc.90fep-2
;A Hexadecimal floating point, uppercase -0XC.90FEP-2
;c Character a
;s String of characters sample
;p Pointer address b8000000
ImportC ""
swprintf(*str.string,format.s,*args,*args1=0,*args2=0,*args3=0,*args4=0,*args5=0,*args6=0,*args7=0,*args8=0)
EndImport
Global str.s{128}
Global *pointer=@str
swprintf(@str,"<h2>This is the address of the output string %p!!!</h2><p>This is a string, %s</p>",*pointer,@"hello")
Debug str
Debug Hex(@str)
Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 10:30 pm
by mk-soft
I can't confirm it on Ubuntu 18.04 X64. Here is an 8 byte align to the next parameter.
Have once a beta version created with calculate the align to next parameter.
Please check the value 'param_align'.
Beta v2.09
Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 10:43 pm
by luis
@mk-soft
Can you confirm my findings enabling the Purifier ? See my edited post.
The version you just posted where the offset is calculated works with the Purifier on or off, thanks.
I hope this is reliable enough and the size of the "cookies" used by the Purifier is not going to change in some strange way where this calculation is not going to work anymore but I doubt it.
Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 10:47 pm
by luis
@idle
Thanks, I tried to import sprintf from the C lib but afaik it doesn't work with floats and doubles, just integers and strings.
If you got it working I would like to see how, because it has the advantage you can pass literal values and values returned from functions instead of just addresses of variables
This one in PB it's very nice, but you have to store values in temporary variables sometimes, even when it shouldn't be necessary.
Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 11:21 pm
by mk-soft
luis wrote:@mk-soft
Can you confirm my findings enabling the Purifier ? See my edited post.
The version you just posted where the offset is calculated works with the Purifier on or off, thanks.
I hope this is reliable enough and the size of the "cookies" used by the Purifier is not going to change in some strange way where this calculation is not going to work anymore but I doubt it.
I can confirm with compiler option Purifier.
Update v2.09
- Fixed compiler option Purifier
Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 11:23 pm
by luis
Thanks.
And thanks for the code

Re: Format string with some values like sprintf (C) - Update
Posted: Wed Jul 18, 2018 11:52 pm
by idle
luis wrote:@idle
Thanks, I tried to import sprintf from the C lib but afaik it doesn't work with floats and doubles, just integers and strings.
If you got it working I would like to see how, because it has the advantage you can pass literal values and values returned from functions instead of just addresses of variables
This one in PB it's very nice, but you have to store values in temporary variables sometimes, even when it shouldn't be necessary.
I've got no idea why it doesn't work with floats or doubles really weird.
Re: Format string with some values like sprintf (C) - Update
Posted: Thu Jul 19, 2018 12:41 am
by skywalk
Re: Format string with some values like sprintf (C) - Update
Posted: Thu Jul 19, 2018 5:50 am
by wilbert
idle wrote:luis wrote:@idle
Thanks, I tried to import sprintf from the C lib but afaik it doesn't work with floats and doubles, just integers and strings.
If you got it working I would like to see how, because it has the advantage you can pass literal values and values returned from functions instead of just addresses of variables
This one in PB it's very nice, but you have to store values in temporary variables sometimes, even when it shouldn't be necessary.
I've got no idea why it doesn't work with floats or doubles really weird.
Probably the x64 calling convention.
On Windows, the first four floating point arguments are passed through XMM0 - XMM3.
On Linux and MacOS it's the first eight floating point arguments (XMM0 - XMM7).
Therefore you need to specify already in the import statement the correct type for the arguments.