vsnprintf and characters

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

vsnprintf and characters

Stefan Schmiedl
I defined a method for vsnprintf to make life
easier and found the following behaviour:

CRTLibrary default vsnprintf: s
        count: 100 format: '%c-%d-%03d-%03d'
        withArguments: (OrderedCollection new
                add: $V;
                add: 5; add: 13;
                add: 46; yourself).
               
this prints as '$-5-013-046', which is not quite
what I expected.

Using add: $V codePoint gives the expected result
of 'V-5-013-046' but seems to be more clumsy than
necessary.

How are characters passed to external methods?
Why are they not passed as I expect them to be? :-)

later,
s.

btw: using an external method was *much* easier than
I expected :)

--
Stefan Schmiedl
EDV-Beratung, Programmierung, Schulung
Loreleystr. 5, 94315 Straubing, Germany
Tel. (0 94 21) 74 01 06, Fax (0 94 21) 74 01 21
Public Key: http://xss.de/stefan.public

shhhh ... I can't hear my code!


Reply | Threaded
Open this post in threaded view
|

Re: vsnprintf and characters

Blair McGlashan
"Stefan Schmiedl" <[hidden email]> wrote in message
news:a6auai$d5s7h$[hidden email]...

> I defined a method for vsnprintf to make life
> easier and found the following behaviour:
>
> CRTLibrary default vsnprintf: s
>         count: 100 format: '%c-%d-%03d-%03d'
>         withArguments: (OrderedCollection new
>                 add: $V;
>                 add: 5; add: 13;
>                 add: 46; yourself).
>
> this prints as '$-5-013-046', which is not quite
> what I expected.
>
> Using add: $V codePoint gives the expected result
> of 'V-5-013-046' but seems to be more clumsy than
> necessary.
>
> How are characters passed to external methods?
> Why are they not passed as I expect them to be? :-)

How have you declared the function wrapper method?

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: vsnprintf and characters

Stefan Schmiedl
On Mon, 11 Mar 2002 15:54:43 -0000,
Blair McGlashan <[hidden email]> wrote:
>
> How have you declared the function wrapper method?
>

ok, here we go:
this is the relevant part of my program (modulo possible typos).

CRTLibrary>>_vsnprintf: buffer count: maxbuf format: format
  withArguments: vaArgs

  <cdecl: sdword _vsnprintf lpvoid sdword lpstr lpvoid>
  ^self invalidCall

String>>sprintfWithArguments: aCollection

  | n crt buf size coll |

  crt := CRTLibrary default.
  size := self size + 64.
  buf := String new: size.
  coll := DWORDArray new: aCollection size.
  aCollection keysAndValuesDo: [ :i :a |
    coll at: i put: (a isInteger ifTrue: [a] ifFalse [a yourAddress]) ].
  [ n := crt _vsnprintf: buf count: size format: self withArguments: coll.
    n < 0 ] whileTrue: [ size := size * 2 ].
  ^buf copyFrom: 1 to: n


Workspace:
'%c' sprintfWithArguments: (Array with: $V) "is displayed as '$'"


thanks for taking a look.

s.
--
Stefan Schmiedl
EDV-Beratung, Programmierung, Schulung
Loreleystr. 5, 94315 Straubing, Germany
Tel. (0 94 21) 74 01 06, Fax (0 94 21) 74 01 21
Public Key: http://xss.de/stefan.public

shhhh ... I can't hear my code!


Reply | Threaded
Open this post in threaded view
|

Re: vsnprintf and characters

Blair McGlashan
"Stefan Schmiedl" <[hidden email]> wrote in message
news:a6jagk$ee50j$[hidden email]...

> ... [snip]....
> String>>sprintfWithArguments: aCollection
>
>   | n crt buf size coll |
>
>   crt := CRTLibrary default.
>   size := self size + 64.
>   buf := String new: size.
>   coll := DWORDArray new: aCollection size.
>   aCollection keysAndValuesDo: [ :i :a |
>     coll at: i put: (a isInteger ifTrue: [a] ifFalse [a yourAddress]) ].
>   [ n := crt _vsnprintf: buf count: size format: self withArguments: coll.
>     n < 0 ] whileTrue: [ size := size * 2 ].
>   ^buf copyFrom: 1 to: n
>...

Well you are passing all non-Integer arguments by their address. The address
of a Character object will not be that of its "codePoint", and in any case
the printf() family expect the %c format character to be associated with a
32-bit integer codePoint value, not the address of the object. Frankly
printf() style formatting does not mesh terribly well with object-oriented
languages, but if you really want to do this in a generic way I suspect you
will need to define a new polymorphic conversion in Object with appropriate
overrides.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

String formatting, [was Re: vsnprintf and characters]

Stefan Schmiedl
On Wed, 13 Mar 2002 09:08:02 -0000,
Blair McGlashan <[hidden email]> wrote:

> "Stefan Schmiedl" <[hidden email]> wrote in message
> news:a6jagk$ee50j$[hidden email]...
>> ... [snip]....
>> String>>sprintfWithArguments: aCollection
>>
>>   | n crt buf size coll |
>>
>>   crt := CRTLibrary default.
>>   size := self size + 64.
>>   buf := String new: size.
>>   coll := DWORDArray new: aCollection size.
>>   aCollection keysAndValuesDo: [ :i :a |
>>     coll at: i put: (a isInteger ifTrue: [a] ifFalse [a yourAddress]) ].
>>   [ n := crt _vsnprintf: buf count: size format: self withArguments: coll.
>>     n < 0 ] whileTrue: [ size := size * 2 ].
>>   ^buf copyFrom: 1 to: n
>>...
>
> Well you are passing all non-Integer arguments by their address. The address
> of a Character object will not be that of its "codePoint", and in any case

ah, yes, of course, stupid me. thanks. I wrongly assumed that characters
have an immediate representation, too, since they fit into smallints...

> the printf() family expect the %c format character to be associated with a
> 32-bit integer codePoint value, not the address of the object. Frankly
> printf() style formatting does not mesh terribly well with object-oriented

yup. I really miss ruby's embedded string expansion, where I can do
the kind of stuff I need quite elegantly.

makes me wonder ... perhaps I am using a totally wrong approach.

So let's just ask for some public opinion:

I use "Article" instances with instance variables
"kind", "season", "provider", "group", which are a character and three numbers
I need some printable label, which I would create in Smalltalk with
the following sequence:

  kind printString , '-' , season printString , '-' ,
    provider printString , '-' , group printString

which would give something like 'V-1-234-567'.
In Ruby I would write

  "#{kind}-#{season}-#{provider}-#{group}"

which is much more readable and compact. Ruby interprets the expressions
inside the braces, which btw, can be any expression, and the resulting
object is sent the message to_a, upon which it yields a string representation.

What is the typical Smalltalk way of achieving this?

Thanks,
s.
--
Stefan Schmiedl
EDV-Beratung, Programmierung, Schulung
Loreleystr. 5, 94315 Straubing, Germany
Tel. (0 94 21) 74 01 06, Fax (0 94 21) 74 01 21
Public Key: http://xss.de/stefan.public

shhhh ... I can't hear my code!


Reply | Threaded
Open this post in threaded view
|

Re: String formatting, [was Re: vsnprintf and characters]

Don Rylander-2
Stefan,
"Stefan Schmiedl" <[hidden email]> wrote in message
news:a6odeq$fsbf3$[hidden email]...
[...]
> I use "Article" instances with instance variables
> "kind", "season", "provider", "group", which are a character and three
numbers

> I need some printable label, which I would create in Smalltalk with
> the following sequence:
>
>   kind printString , '-' , season printString , '-' ,
>     provider printString , '-' , group printString
>
> which would give something like 'V-1-234-567'.
> In Ruby I would write
>
>   "#{kind}-#{season}-#{provider}-#{group}"
Why not just override #displayOn: (if it's for the user to see) or #printOn:
(for the developer)?  Something like:

displayOn: aStream

    aStream
        display: kind;
        nextPut: $-;
        display: season;
        nextPut: $-;
        display: provider;
        nextPut: $-;
        display: group.

Don
>
> which is much more readable and compact. Ruby interprets the expressions
> inside the braces, which btw, can be any expression, and the resulting
> object is sent the message to_a, upon which it yields a string
representation.

>
> What is the typical Smalltalk way of achieving this?
>
> Thanks,
> s.
> --
> Stefan Schmiedl
> EDV-Beratung, Programmierung, Schulung
> Loreleystr. 5, 94315 Straubing, Germany
> Tel. (0 94 21) 74 01 06, Fax (0 94 21) 74 01 21
> Public Key: http://xss.de/stefan.public
>
> shhhh ... I can't hear my code!


Reply | Threaded
Open this post in threaded view
|

Re: String formatting, [was Re: vsnprintf and characters]

Stefan Schmiedl
On Wed, 13 Mar 2002 18:56:55 -0600,
Don Rylander <[hidden email]> wrote:

> Stefan,
> "Stefan Schmiedl" <[hidden email]> wrote in message
> news:a6odeq$fsbf3$[hidden email]...
> [...]
>> I use "Article" instances with instance variables
>> "kind", "season", "provider", "group", which are a character and three
> numbers
>> I need some printable label, which I would create in Smalltalk with
>> the following sequence:
>>
>>   kind printString , '-' , season printString , '-' ,
>>     provider printString , '-' , group printString
>>
>> which would give something like 'V-1-234-567'.
>> In Ruby I would write
>>
>>   "#{kind}-#{season}-#{provider}-#{group}"
> Why not just override #displayOn: (if it's for the user to see) or #printOn:
> (for the developer)?  Something like:

ahhh, yes. I had forgotten about displayOn:, thanks for reminding me.

>
> displayOn: aStream
>
>     aStream
>         display: kind;
>         nextPut: $-;
>         display: season;
>         nextPut: $-;
>         display: provider;
>         nextPut: $-;
>         display: group.
>

I think I will do some refactoring with some Article>>displayOn:formattedAs:
methods that should clean things up a lot.

Object>>displayOn: aStream formattedAs: formatter

        self perform: ('formatAs' , formatter asString , 'On:') asSymbol
             with: aStream

Article>>formatAsLabelOn: aStream

        aStream
                display ....

and then use

Article new displayOn: Transcript formattedAs: #Label

modulo typos etc., as I am typing this right into my newsreader.

thanks,
s.
--
Stefan Schmiedl
EDV-Beratung, Programmierung, Schulung
Loreleystr. 5, 94315 Straubing, Germany
Tel. (0 94 21) 74 01 06, Fax (0 94 21) 74 01 21
Public Key: http://xss.de/stefan.public

shhhh ... I can't hear my code!