blob: a759f1564c6cabc1d90f478dd34f1064c8b6bd39 [file] [log] [blame]
// REQUIRED_ARGS: -g
// REQUIRED_ARGS(linux freebsd dragonflybsd): -L-export-dynamic
// PERMUTE_ARGS:
// DISABLED: osx
import core.stdc.stdio;
void main()
{
fun(1);
fun(2);
fun(3);
#line 30
fun(4);
foo(1, 10);
foo(2, 10);
foo(3, 10);
#line 40
foo(4, 10);
}
void fun(int n, int defParam = 10)
{
try
{
if (n == 4)
throw new Exception("fun");
}
catch(Exception e)
{
string s = e.toString();
printf("%.*s\n", cast(int)s.length, s.ptr);
int line = lineInMain(e.toString());
assert(line >= 30 && line <= 32); // return address might be next statement
}
}
void foo(int n, int m)
{
try
{
if (n == 4)
throw new Exception("foo");
}
catch(Exception e)
{
string s = e.toString();
printf("%.*s\n", cast(int)s.length, s.ptr);
int line = lineInMain(e.toString());
assert(line >= 40 && line <= 41); // return address might be next statement
}
}
int lineInMain(string msg)
{
// find line number of _Dmain in stack trace
// on linux: file.d:line _Dmain [addr]
// on windows: addr in _Dmain at file.d(line)
int line = 0;
bool mainFound = false;
for (size_t pos = 0; pos + 6 < msg.length; pos++)
{
if (msg[pos] == '\n')
{
line = 0;
mainFound = false;
}
else if ((msg[pos] == ':' || msg[pos] == '(') && line == 0)
{
for (pos++; pos < msg.length && msg[pos] >= '0' && msg[pos] <= '9'; pos++)
line = line * 10 + msg[pos] - '0';
if (line > 0 && mainFound)
return line;
}
else if (msg[pos .. pos + 6] == "_Dmain" || msg[pos .. pos + 6] == "D main")
{
mainFound = true;
if (line > 0 && mainFound)
return line;
}
}
return 0;
}