digitalmars.D.learn - forward variadic arguments
- Frank Benoit (6/6) Jun 15 2006 void execSql( char[] aSql, ... ){
- Deewiant (10/18) Jun 15 2006 You'll need to do it "manually" by calling the std.format.doFormat funct...
- Frank Benoit (6/16) Jun 15 2006 And what happend to my format string 'aSql' ? :)
- Deewiant (22/41) Jun 15 2006 Oh, whoops! :-)
- Tom S (38/45) Jun 15 2006 I know it's evil and stuff, but I had to do this :D
- Daniel Keep (13/26) Jun 16 2006 One of the projects I've been thinking about doing is writing a library
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?
Jun 15 2006
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);
}
Jun 15 2006
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);
Jun 15 2006
Frank Benoit wrote: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 }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);
Jun 15 2006
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 +/
Jun 15 2006
Tom S wrote:Frank Benoit wrote: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/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]
Jun 16 2006









Deewiant <deewiant.doesnotlike.spam gmail.com> 