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

Code: Select all

  *args + SizeOf ( Integer ) 
            Break
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

Code: Select all

...
Removed
...

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 :wink:

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.