| |
 | Posted by Derek Parnell in reply to AJG | Permalink Reply |
|
Derek Parnell 
| On Thu, 15 Sep 2005 02:45:20 -0400, AJG wrote:
> Hi there,
>
> Is there a version of writef or doFormat that doesn't expect printf-style formatting?
>
> A lot of times what I wish to do is simply print a series of variables, without having to worry about whether there's a '%' in there.
>
> So, for example:
>
> foo("%s%d ", 42, " %x ", 13.3);
>
> Would print:
>
> "%s%d 42 %x 13.3"
>
> Is there currently a way to do this with a special function?
>
> I think there should be a version of doFormat simply prints everything it encounters without formatting it. Does anybody have anything like that?
>
> I quickly built two versions, but I have a feeling there's a better way to do this. Any help is appreciated.
>
> The first version uses std.boxer, which is a little inefficient for a simple print function:
>
> void echo(...) {
> foreach (std.boxer.Box b; std.boxer.boxArray(_arguments, _argptr))
> writef("%s", b.toString);
> }
>
> Then, I took a look at std.boxer's own toString function and modified it a little to get this:
>
> void echo(...) {
> foreach (TypeInfo ti; _arguments) {
> if (ti is null) {
> writef("<null>");
> continue;
> }
>
> TypeInfo[2] args;
> const size_t ssize = string.sizeof;
> void[] data = new void[ssize + ti.tsize];
> string format = "%s", result;
>
> void putc(dchar c) { std.utf.encode(result, c); }
> args[0] = typeid(string);
> args[1] = ti;
> data[0 .. ssize] = (cast (void*) &format)[0 .. ssize];
> data[ssize .. $] = _argptr[0 .. ti.tsize];
> std.format.doFormat(&putc, args, data);
> delete data;
> writef("%s", result);
> _argptr += (ti.tsize + int.sizeof - 1) & ~(int.sizeof - 1);
> }
> }
>
> Any suggestions? I think std.stdio should have something like this built-in.
Here is my 'stringer' module. It works for every thing except structs and non-character arrays.
<code>
private
{
import std.string;
import std.utf;
import std.stdarg;
import std.cstream;
}
char[] stringer(TypeInfo[] pArgTypes, va_list pArgValues)
{
char[] lResult;
foreach (TypeInfo lTI; pArgTypes)
{
if (lTI is typeid(int))
{
lResult ~= std.string.toString(va_arg!(int)(pArgValues));
}
else if (lTI is typeid(uint))
{
lResult ~= std.string.toString(va_arg!(uint)(pArgValues));
}
else if (lTI is typeid(bit))
{
lResult ~= std.string.toString(va_arg!(bit)(pArgValues));
}
else if (lTI is typeid(byte))
{
lResult ~= std.string.toString(va_arg!(byte)(pArgValues));
}
else if (lTI is typeid(ubyte))
{
lResult ~= std.string.toString(va_arg!(ubyte)(pArgValues));
}
else if (lTI is typeid(short))
{
lResult ~= std.string.toString(va_arg!(short)(pArgValues));
}
else if (lTI is typeid(ushort))
{
lResult ~= std.string.toString(va_arg!(ushort)(pArgValues));
}
else if (lTI is typeid(long))
{
lResult ~= std.string.toString(va_arg!(long)(pArgValues));
}
else if (lTI is typeid(ulong))
{
lResult ~= std.string.toString(va_arg!(ulong)(pArgValues));
}
else if (lTI is typeid(float))
{
lResult ~= std.string.toString(va_arg!(float)(pArgValues));
}
else if (lTI is typeid(double))
{
lResult ~= std.string.toString(va_arg!(double)(pArgValues));
}
else if (lTI is typeid(real))
{
lResult ~= std.string.toString(va_arg!(real)(pArgValues));
}
else if (lTI is typeid(ireal))
{
lResult ~= std.string.toString(va_arg!(ireal)(pArgValues));
}
else if (lTI is typeid(creal))
{
lResult ~= std.string.toString(va_arg!(creal)(pArgValues));
}
else if (lTI is typeid(ifloat))
{
lResult ~= std.string.toString(va_arg!(ifloat)(pArgValues));
}
else if (lTI is typeid(cfloat))
{
lResult ~= std.string.toString(va_arg!(cfloat)(pArgValues));
}
else if (lTI is typeid(idouble))
{
lResult ~= std.string.toString(va_arg!(idouble)(pArgValues));
}
else if (lTI is typeid(cdouble))
{
lResult ~= std.string.toString(va_arg!(cdouble)(pArgValues));
}
else if (lTI is typeid(char))
{
lResult ~= std.string.toString(va_arg!(char)(pArgValues));
}
else if (lTI is typeid(char[]))
{
lResult ~= va_arg!(char[])(pArgValues);
}
else if (lTI is typeid(wchar))
{
wchar[1] lTemp;
lTemp[0] = va_arg!(wchar)(pArgValues);
lResult ~= toUTF8(lTemp[0..0]);
}
else if (lTI is typeid(wchar[]))
{
lResult ~= toUTF8(va_arg!(wchar[])(pArgValues));
}
else if (lTI is typeid(dchar))
{
dchar[1] lTemp;
lTemp[0] = va_arg!(dchar)(pArgValues);
lResult ~= toUTF8(lTemp[0..0]);
}
else if (lTI is typeid(dchar[]))
{
lResult ~= toUTF8(va_arg!(dchar[])(pArgValues));
}
else
{
if (lTI.tsize() == 0)
pArgValues += 8; // Skip over bad data
else
lResult ~= (va_arg!(Object)(pArgValues)).toString;
}
}
return lResult;
}
char[] toString(...)
{
return stringer(_arguments, _argptr);
}
void write(...)
{
dout.puts(stringer(_arguments, _argptr) );
dout.flush();
}
void writeln(...)
{
dout.puts(stringer(_arguments, _argptr) );
dout.puts("\n");
dout.flush();
}
</code>
For example ...
<code>
import stringer;
class Foo
{
char[] toString()
{
return " i am foo ";
}
}
void main()
{
Foo f = new Foo;
writeln( "one=", 1, " %but ", 23.0L, " is "d, true, ':', f, ":"w);
}
</code>
--
Derek Parnell
Melbourne, Australia
15/09/2005 7:44:18 PM
|