printf: stringFormat args: tab
������ | argNumber functionArgs functionPrototype methodCorpse methodSelector argsArray |
������
������ ((tab size % 2) = 0) ifFalse: [
������ ������ Transcript show: 'error'.
������ ������ ^self.
������ ].
������ argNumber := 0.
������ functionPrototype := 'printf: stringFormat'.
������ functionArgs := ''.
������ methodCorpse := ''.
������ argsArray := (Array new: (tab size / 2) + 1).
������ argsArray at: 1 put: stringFormat.
������
������ 1 to: tab size by: 2 do: [ :i |
������ ������ functionPrototype := functionPrototype, ' arg', argNumber asString, ': ', (tab at: i) asString, argNumber asString.
������ ������ functionArgs := functionArgs, ' ', (tab at: i) asString, ' ', (tab at: i) asString, argNumber asString, ','.
������ ������ argsArray at: argNumber + 2 put: (tab at: i + 1).
������ ������ argNumber := argNumber + 1.
������ ].
������ functionArgs := functionArgs allButLast.
������
������ methodCorpse := functionPrototype, Character cr asString, '������ <primitive: #primitiveNativeCall module: #NativeBoostPlugin>', Character cr asString, Character cr asString, '������ ^self nbCall: #( void printf ( String stringFormat,', functionArgs asString, ' ) )', Character cr asString, '������ ������ module: NativeBoost CLibrary'.
������ methodSelector := self class compile: methodCorpse.
������
������ self perform: methodSelector withArguments: argsArray.
Then you can call it like that :
MyClass printf: 'Test of printf. String: %s, Int : %d, Long: %ld, Char: %c, Double: %lf' args: { 'String'. 'This is a string'. 'int'. 100. 'long'. 10000000. 'char'. 89. 'double'. 3.14159 }.
I also tried it for some other variadic functions and, on my computer (I am running archlinux), it seemed to work for every type of argument except "float". It works fine for "double" though.
For "char" you need to pass the integer ASCII value directly for it to work. I tried with "Character value: xxx" but it didn't work.
I know that this is very hackish and very bad, and I am aware it has some drawbacks. Moreover I am not even sure it will work everytime.
But for now it seems to work ...