Special Token __FUNCTION__

Nick Sabalausky a at a.a
Mon Sep 7 13:14:33 PDT 2009


"Robert Jacques" <sandford at jhu.edu> wrote in message 
news:op.uzwccwqu26stm6 at sandford.myhome.westell.com...
> On Mon, 07 Sep 2009 12:41:46 -0400, Byron Heads <wyverex.cypher at gmail.com> 
> wrote:
>
>> I've looked through the lex documents but there seems to be no special 
>> token
>> to get the current calling function.
>>
>> In c you can use the __func__ token to get the current function.
>>
>> I thinking adding __FUNCTION__ would be useful for things like logging.
>>

It's been suggested a lot, but it would also be useful to have a whole bunch 
of other similar things, like __CLASS__, __TEMPLATE__, etc., so the ensuing 
discussions generally end up favoring a way to get all of that through an 
expanded compile-time reflection (which has yet to materialize).

>> Also is there a nice way to replace logging macros?  I often have a 
>> logger
>> that looks like
>> logmsg( int level, uint line, char* func, char* file, char[] msg, ... );
>>
>> then I would write some macros like:
>> #define LOGDEBUG( m, ... )  logmsg( LVL_DEBUG, __LINE__, __func__, 
>> __FILE__, msg, __VA_ARGS__ )
>>
>> thus i would only have to do
>> LOGDEBUG( "SOME STRING with formatting", formatting args.. )
>>

Templates to the rescue! :) From my "SemiTwist D Tools" ( 
http://www.dsource.org/projects/semitwist ) :

---------------------------------------------------------
/**
Easy way to output file/line. Useful for debugging.

Usage:

----
mixin(trace!());
funcSuspectedOfCrashing()
mixin(trace!("--EASY TO VISUALLY GREP--"));
theRealCauseOfCrash()
mixin(trace!());
----

Turns Into:

----
Stdout.formatln("{}({}): trace", __FILE__, __LINE__);
funcSuspectedOfCrashing()
Stdout.formatln("{}{}({}): trace", "--EASY TO VISUALLY GREP--", __FILE__, 
__LINE__);
theRealCauseOfCrash()
Stdout.formatln("{}({}): trace", __FILE__, __LINE__);
----

Example Output:

----
C:\path\file.d(1): trace
--EASY TO VISUALLY GREP--: C:\path\file.d(3): trace
{segfault!}
----
*/
template trace(char[] prefix="")
{
 static if(prefix=="")
  const char[] trace =
   `Stdout.formatln("{}({}): trace", __FILE__, __LINE__);`;
 else
  const char[] trace =
   `Stdout.formatln("{}: {}({}): trace", `~prefix.stringof~`, __FILE__, 
__LINE__);`;
 //pragma(msg, "trace: " ~ trace);
}
---------------------------------------------------------

That can, of course, be adjusted to do whatever logging you need instead of 
just tracing to Stdout.

>
> You can put __LINE__, etc into template parameters. For example:
>
> void echo(int T = __LINE__, U...)(U msg) { writeln(T,": ",msg); }

Is that a D2-only thing? Because I've tried that (in D1) and it never seemed 
to work. (Also, I think __LINE__ evaluates to a long literal...or maybe it's 
just unsigned...either way, I know it's not "int", at least not in D1.)





More information about the Digitalmars-d mailing list