Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
June 15, 2006 forward variadic arguments | ||||
---|---|---|---|---|
| ||||
void execSql( char[] aSql, ... ){ char[] sql = std.string.format( aSql, _arguments, _argptr ); database.exec( sql ); } The forwarding of all arguments to format() seams not to work. how can I do this? |
June 15, 2006 Re: forward variadic arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | Frank Benoit wrote:
> void execSql( char[] aSql, ... ){
> char[] sql = std.string.format( aSql, _arguments, _argptr );
> database.exec( sql );
> }
>
> The forwarding of all arguments to format() seams not to work.
> how can I do this?
>
You'll need to do it "manually" by calling the std.format.doFormat function.
void execSql(char[] aSql, ...) {
char[] sql;
void putc(dchar c) {
sql ~= c;
}
std.format.doFormat(&putc, _arguments, _argptr);
database.exec(sql);
}
|
June 15, 2006 Re: forward variadic arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Deewiant |
> void execSql(char[] aSql, ...) {
> char[] sql;
> void putc(dchar c) {
> sql ~= c;
> }
>
> std.format.doFormat(&putc, _arguments, _argptr);
>
> database.exec(sql);
> }
And what happend to my format string 'aSql' ? :)
TypeInfo[] ti;
ti ~= aSql.typeinfo;
ti ~= _arguments
void* p = ????;
std.format.doFormat(&putc, ti, p);
|
June 15, 2006 Re: forward variadic arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | Frank Benoit wrote:
>> void execSql(char[] aSql, ...) {
>> char[] sql;
>> void putc(dchar c) {
>> sql ~= c;
>> }
>>
>> std.format.doFormat(&putc, _arguments, _argptr);
>>
>> database.exec(sql);
>> }
>
> And what happend to my format string 'aSql' ? :)
>
> TypeInfo[] ti;
> ti ~= aSql.typeinfo;
> ti ~= _arguments
>
> void* p = ????;
> std.format.doFormat(&putc, ti, p);
Oh, whoops! :-)
I guess you could try a hack like that. I think you'll have to use std.stdarg - somehow; I've never done this myself - to collect the arguments themselves into an array and then pass the address of the first element of that array as the equivalent of _argptr. BTW, "aSql.typeinfo" is deprecated: use "typeid(typeof(aSql))" or just "typeid(char[])" if you're confident you'll never change its type.
Personally, I'd just change the function signature to "void execSql(...)". It gives a bit more versatility, the following are equivalent:
execSql("%d hello %d", a, b);
execSql(a, " hello ", b);
execSql("%d hello ", a, b);
If you really want to force the first parameter to be char[], I think the only way to be sure (apart from that hackish approach, of course :-P) is to assert it at runtime:
void execSql(...)
in {
assert (_arguments[0] == typeid(char[]));
} body {
// the code
}
|
June 15, 2006 Re: forward variadic arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Frank Benoit | Frank Benoit wrote: > void execSql( char[] aSql, ... ){ > char[] sql = std.string.format( aSql, _arguments, _argptr ); > database.exec( sql ); > } > > The forwarding of all arguments to format() seams not to work. > how can I do this? I know it's evil and stuff, but I had to do this :D import std.stdio; /** there's a simpler solution, actually, but it makes the assumption, that _argptr - xsize == &x; without exploiting this assumption, the following code should even be portable ;D */ void foo(char[] x, ...) { TypeInfo[] args = _arguments.dup; void* ptr = _argptr; const size_t xsize = (char[]).sizeof; ubyte[xsize] ptrVal = (cast(ubyte*)ptr)[0 .. xsize]; // we'll be writing to the stack, this array will store the old values ubyte[xsize] backup; // this will hold the binary contents of 'x' ubyte[xsize] newVal; // make space for the value we'll be inserting to the stack ptr -= xsize; // it will tell writefx to expect another argument args = typeid(char[]) ~ args; // make a backup of the old value of ptrVal backup[] = ptrVal[]; // and get the new values into the temp array newVal[] = (cast(ubyte*)&x)[0 .. xsize]; // finally, write the new values ptrVal[] = newVal[]; writefx(stdout, args, ptr, true); // restore the old stack data ptrVal[] = backup[]; } void main() { foo("foo ", "bar", 1, 2, 3); } -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/ |
June 16, 2006 Re: forward variadic arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S wrote: > Frank Benoit wrote: >> void execSql( char[] aSql, ... ){ >> char[] sql = std.string.format( aSql, _arguments, _argptr ); >> database.exec( sql ); >> } >> >> The forwarding of all arguments to format() seams not to work. >> how can I do this? > > I know it's evil and stuff, but I had to do this :D > > [snip evil but quite handy code] > One of the projects I've been thinking about doing is writing a library for doing programmatic function calls, which would allow things like this to actually be portable :P Of course, I've been putting it off since Walter still hasn't documented the calling convention for D, and I didn't even realize until a month or so ago that it (sometimes) passes an argument in EAX >_< -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/ |
Copyright © 1999-2021 by the D Language Foundation