www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Special Token __FUNCTION__

reply Byron Heads <wyverex.cypher gmail.com> writes:
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.

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.. )

-B
Sep 07 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Byron Heads:

 I thinking adding __FUNCTION__ would be useful for things like logging.
Recently I have asked something similar (to be used as the name of the function inside a function, useful for recursive calls that keep working even when the function name changes) But most of the ideas I suggest here get dispersed like tears in rain :-) Bye, bearophile
Sep 07 2009
next sibling parent "Saaa" <empty needmail.com> writes:
 But most of the ideas I suggest here get dispersed like tears in rain :-)
I read them ;-)
Sep 07 2009
prev sibling parent Byron Heads <wyverx.cypher gmail.com> writes:
bearophile Wrote:

 Byron Heads:
 
 I thinking adding __FUNCTION__ would be useful for things like logging.
Recently I have asked something similar (to be used as the name of the function inside a function, useful for recursive calls that keep working even when the function name changes) But most of the ideas I suggest here get dispersed like tears in rain :-) Bye, bearophile
Sad.. I think it would be fairly simple to do what is done in gcc. Simply add a static const char[] __FUNCTION__ = "Function Name"; to the start of every function. same with classes. Each class type would have an auto defined static const char[] __CLASS__ = "Class Name"; added as a public type. Class methods could have a __FUNCTION__ where static conat char[] __FUNCTION__ = __CLASS__ ~ "Method Name"; It would be like the program below. 1 module func; 2 3 import tango.io.Stdout; 4 5 class A 6 { 7 static const char[] __CLASS__ = "A"; 8 void foo() 9 { 10 static const char[] __FUNCTION__ = __CLASS__ ~ ".foo"; 11 Stdout.format( "{}\n", __FUNCTION__ ); 12 } 13 } 14 15 class B: A 16 { 17 static const char[] __CLASS__ = "B"; 18 void foo() 19 { 20 static const char[] __FUNCTION__ = __CLASS__ ~ ".foo"; 21 Stdout.format( "{}\n", __FUNCTION__ ); 22 } 23 } 24 25 char[] bar() 26 { 27 static const char[] __FUNCTION__ = "bar"; 28 return( __FUNCTION__ ); 29 } 30 31 void main() 32 { 33 static const char[] __FUNCTION__ = "main"; 34 35 auto a = new A(); 36 auto b = new B(); 37 38 Stdout.format( "[{}] main(): {} \n", __LINE__, __FUNCTION__ ); 39 Stdout.format( "[{}] bar(): {}\n", __LINE__, bar() ); 40 41 Stdout.format( "[{}] A a: {}\n", __LINE__, a.__CLASS__ ); 42 Stdout.format( "[{}] B B: {}\n", __LINE__, b.__CLASS__ ); 43 Stdout.format( "[{}] B (cast(A)b): {}\n", __LINE__, (cast(A)b).__CLASS__ ); 44 Stdout.format( "[{}] A a.foo(): ", __LINE__ ); 45 a.foo(); 46 Stdout.format( "[{}] B b.foo(): ", __LINE__ ); 47 b.foo(); 48 Stdout.format( "[{}] B (cast(A)b).foo(): ", __LINE__ ); 49 (cast(A)b).foo(); 50 } Results: [43] main(): main [44] bar(): bar [46] A a: A [47] B B: B [48] B (cast(A)b): A [49] A a.foo(): A.foo [51] B b.foo(): B.foo [53] B (cast(A)b).foo(): B.foo
Sep 08 2009
prev sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Mon, 07 Sep 2009 12:41:46 -0400, Byron Heads <wyverex.cypher 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.

 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.. )

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