www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - __FUNC__ in D

reply argl <cavenhaus gmail.com> writes:
Hi, I know this has come aup a few times in the past, but I have not come
across a clear answer.

Is it possible in any way to get the name of the current function for logging
purposes? Something to get the functionality of __FUNC__ in C?
Aug 13 2007
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"argl" <cavenhaus gmail.com> wrote in message 
news:f9qrup$nqe$1 digitalmars.com...
 Hi, I know this has come aup a few times in the past, but I have not come 
 across a clear answer.

 Is it possible in any way to get the name of the current function for 
 logging purposes? Something to get the functionality of __FUNC__ in C?
No.
Aug 14 2007
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Jarrett,

 "argl" <cavenhaus gmail.com> wrote in message
 news:f9qrup$nqe$1 digitalmars.com...
 
 Hi, I know this has come aup a few times in the past, but I have not
 come across a clear answer.
 
 Is it possible in any way to get the name of the current function for
 logging purposes? Something to get the functionality of __FUNC__ in
 C?
 
No.
CTFE anyone? char[] GetLastFnDef(char[] file, int line); use like this: const char[] fn = GetLastFnDef(import(__FILE__), __LINE__);
Aug 14 2007
parent reply argl <me somewhere.com> writes:
That would be wonderful! 
I am getting the following errors though.
Where do I find GetLastFnDef() ?

dmd -Jpath -run ./test.d
test.d(80): Error: undefined identifier GetLastFnDef
test.d(80): Error: need -Jpath switch to import text file test.d
test.d(80): Error: function expected before (), not GetLastFnDef of type int
test.d(80): Error: cannot implicitly convert expression (GetLastFnDef("",80L))
of type int to char[]


BCS Wrote:

 Reply to Jarrett,
 
 "argl" <cavenhaus gmail.com> wrote in message
 news:f9qrup$nqe$1 digitalmars.com...
 
 Hi, I know this has come aup a few times in the past, but I have not
 come across a clear answer.
 
 Is it possible in any way to get the name of the current function for
 logging purposes? Something to get the functionality of __FUNC__ in
 C?
 
No.
CTFE anyone? char[] GetLastFnDef(char[] file, int line); use like this: const char[] fn = GetLastFnDef(import(__FILE__), __LINE__);
Aug 15 2007
parent reply argl <me somewhere.com> writes:
Sorry, stupid me forgot the declaration. I am still getting an error though.

dmd -J/tmp test3.d
test3.d(7): Error: cannot evaluate GetLastFnDef("import
tango.io.Stdout;\x0a\x0achar[] GetLastFnDef(char[] file, int line);\x0a\x0avoid
main()\x0a{\x0a    const char[] fn = GetLastFnDef(import(__FILE__),
__LINE__);\x0a    Stdout (\"hello {}\",
fn).newline;\x0a}\x0a\x0a\x0a\x0a\x0a",7) at compile time

Any help would be appreciated.

argl Wrote:

 That would be wonderful! 
 I am getting the following errors though.
 Where do I find GetLastFnDef() ?
 
 dmd -Jpath -run ./test.d
 test.d(80): Error: undefined identifier GetLastFnDef
 test.d(80): Error: need -Jpath switch to import text file test.d
 test.d(80): Error: function expected before (), not GetLastFnDef of type int
 test.d(80): Error: cannot implicitly convert expression (GetLastFnDef("",80L))
of type int to char[]
 
 
 BCS Wrote:
 
 Reply to Jarrett,
 
 "argl" <cavenhaus gmail.com> wrote in message
 news:f9qrup$nqe$1 digitalmars.com...
 
 Hi, I know this has come aup a few times in the past, but I have not
 come across a clear answer.
 
 Is it possible in any way to get the name of the current function for
 logging purposes? Something to get the functionality of __FUNC__ in
 C?
 
No.
CTFE anyone? char[] GetLastFnDef(char[] file, int line); use like this: const char[] fn = GetLastFnDef(import(__FILE__), __LINE__);
Aug 15 2007
parent reply BCS <BCS pathlink.com> writes:
argl wrote:
 Sorry, stupid me forgot the declaration. I am still getting an error though.
 
 dmd -J/tmp test3.d
 test3.d(7): Error: cannot evaluate GetLastFnDef("import
tango.io.Stdout;\x0a\x0achar[] GetLastFnDef(char[] file, int line);\x0a\x0avoid
main()\x0a{\x0a    const char[] fn = GetLastFnDef(import(__FILE__),
__LINE__);\x0a    Stdout (\"hello {}\",
fn).newline;\x0a}\x0a\x0a\x0a\x0a\x0a",7) at compile time
 
 Any help would be appreciated.
 
 argl Wrote:
 
It's a hypothetical function that doesn't exist (yet). However, it's shouldn't be two hard to wright one that would work for most case.
Aug 15 2007
parent reply argl <me somewhere.com> writes:
BCS Wrote:
 
 It's a hypothetical function that doesn't exist (yet). However, it's 
 shouldn't be two hard to wright one that would work for most case.
I see. Thank you.
Aug 15 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
argl wrote:
 BCS Wrote:
 It's a hypothetical function that doesn't exist (yet). However, it's 
 shouldn't be two hard to wright one that would work for most case.
I see. Thank you.
Quick and dirty! import std.stdio, std.string, std.ctype; alias std.string.tolower tolower; void main() { foo(); bar(); baz(); } void foo() { string fn = FnName(import(__FILE__), __LINE__); writefln(fn); } void bar () { string fn = FnName(import(__FILE__), __LINE__); writefln(fn); } const(char)baz () { string fn = FnName(import(__FILE__), __LINE__); writefln(fn); return cast(const(char))'c'; } string FnName(string file, uint line) { string name; string last; int level; int start; int end; foreach(nLine, s; splitlines(file)) { foreach(ref p; s.split()) { if (p.contains(cast(const(char))'{')) level++; if (p.contains(cast(const(char))'}')) level--; if (level > 0) continue; if (isKeyword(p)) continue; if (p.contains(cast(const(char))'(')) { end = p.find('('); if (end == 0) { p = last; end = p.length; } for(start = end-1; start > 0; start--) { if (!isalnum(p[start])) { start++; break; } } name = p[start..end].dup; } last = p; } if (nLine > line) break; } return name; } bool isKeyword(string word) { return keywords.contains(tolower(word)); } bool contains(T)(T[] arr, T val) { foreach(i; arr) if (i == val) return true; return false; } string[] keywords = [ "abstract", "alias", "align", "asm", "assert", "auto", "body", "bool", "break", "byte", "case", "cast", "catch", "cdouble", "cent", "cfloat", "char", "class", "const", "continue", "creal", "dchar", "debug", "default", "delegate", "delete", "deprecated", "do", "double", "else", "enum", "export", "extern", "false", "final", "finally", "float", "for", "foreach", "foreach_reverse", "function", "goto", "idouble", "if", "ifloat", "import", "in", "inout", "int", "interface", "invariant", "ireal", "is", "lazy", "long", "macro", "mixin", "module", "new", "null", "out", "override", "package", "pragma", "private", "protected", "public", "real", "ref", "return", "scope", "short", "static", "struct", "super", "switch", "synchronized", "template", "this", "throw", "__traits", "true", "try", "typedef", "typeid", "typeof", "ubyte", "ucent", "uint", "ulong", "union", "unittest", "ushort", "version", "void", "volatile", "wchar", "while", "with", "__FILE__", "__LINE__", "__DATE__", "__TIME__", "__TIMESTAMP__", "__VENDOR__", "__VERSION__" ];
Aug 15 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
On 2nd thought I think this only works by some sheer coincidence and fluke!

A better one could definately be written with the DMDFE.

Regan
Aug 15 2007
parent reply BCS <BCS pathlink.com> writes:
Regan Heath wrote:
 On 2nd thought I think this only works by some sheer coincidence and fluke!
The whole idea is a hack. Hacks are only /suposed/ to work when the user does things exactly right
 
 A better one could definately be written with the DMDFE.
yes but do you want to port DMDFE to run using CTFE?
 
 Regan
Aug 15 2007
parent reply Regan Heath <regan netmail.co.nz> writes:
BCS wrote:
 Regan Heath wrote:
 On 2nd thought I think this only works by some sheer coincidence and 
 fluke!
The whole idea is a hack. Hacks are only /suposed/ to work when the user does things exactly right
True. There are many combinations which will break it, i.e. const(char) baz() will get a function called "const", an extra check of p[start..end] using isKeyword would fix a few of these sorts of problems.
 A better one could definately be written with the DMDFE.
yes but do you want to port DMDFE to run using CTFE?
Actually I think I have some code to lex C/C++ here somewhere and with very few changes it would lex D just as well. That would be easier that using a full blown DMDFE port. I might see what I can whip up tomorrow (it's 11pm here). Regan
Aug 15 2007
parent argl <me somewhere.com> writes:
Amazing! I greatly appreciate your help!
Aug 15 2007
prev sibling parent "Rob T" <rob ucora.com> writes:
 No.
The question is "Why not?". For a language that is supposed to have good compile time relfection, and wants to have good runtime relection, this basic inability illustrates an area in dire need of attention. I don't think a solution is to introduce __FUNC__, that will only add on to the already big clutter pile. A more generalized solution is to introduce self-referencing (and then get rid of some of the clutter). Eg void function x() { writeln( typeof(self).stringof ); } Even better, using the uniform calling syntax convention void function x() { writeln( self.typeof.stringof ); } --rt
Sep 18 2012