Parse nested namespaces in break point specifications.
Changed the parser for break point specifications to allow nested namespace qualifiers. Also extended this to the exception command.
Esse commit está contido em:
@@ -671,8 +671,9 @@ void BreakPointInfo::parseBreakPointReached(const std::string &exp,
|
||||
if (offset2 == offset1) goto returnInvalid;
|
||||
name = exp.substr(offset1, offset2-offset1);
|
||||
}
|
||||
if (offset1 < len && exp[offset1] == '\\') {
|
||||
m_namespace = name;
|
||||
while (offset1 < len && exp[offset1] == '\\') {
|
||||
if (!m_namespace.empty()) m_namespace += "\\";
|
||||
m_namespace += name;
|
||||
offset1 += 1;
|
||||
auto offset2 = scanName(exp, offset1);
|
||||
// check for {namespace}\{something that is not a name}
|
||||
@@ -756,32 +757,57 @@ parseUrl:
|
||||
|
||||
returnInvalid:
|
||||
m_valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
void BreakPointInfo::parseExceptionThrown(const std::string &exp) {
|
||||
TRACE(2, "BreakPointInfo::parseExceptionThrown\n");
|
||||
string input = exp;
|
||||
|
||||
// everything after @ is URL
|
||||
size_t pos = input.find('@');
|
||||
if (pos != string::npos) {
|
||||
m_url = input.substr(pos + 1);
|
||||
input = input.substr(0, pos);
|
||||
string name;
|
||||
auto len = exp.length();
|
||||
auto offset0 = 0;
|
||||
// Skip over a leading backslash
|
||||
if (len > 0 && exp[0] == '\\') offset0++;
|
||||
auto offset1 = scanName(exp, offset0);
|
||||
// check that exp starts with a name
|
||||
if (offset1 == offset0) goto returnInvalid;
|
||||
name = exp.substr(offset0, offset1-offset0);
|
||||
if (name.empty()) {
|
||||
if (len > offset1 && exp[offset1] == '\\') offset1++;
|
||||
auto offset2 = scanName(exp, offset1);
|
||||
// check for {something other than a name}
|
||||
if (offset2 == offset1) goto returnInvalid;
|
||||
name = exp.substr(offset1, offset2-offset1);
|
||||
}
|
||||
|
||||
pos = input.find("::");
|
||||
if (pos != string::npos) {
|
||||
if (pos) {
|
||||
m_namespace = input.substr(0, pos);
|
||||
}
|
||||
m_class = input.substr(pos + 2);
|
||||
while (offset1 < len && exp[offset1] == '\\') {
|
||||
if (!m_namespace.empty()) m_namespace += "\\";
|
||||
m_namespace += name;
|
||||
offset1 += 1;
|
||||
auto offset2 = scanName(exp, offset1);
|
||||
// check for {namespace}\{something that is not a name}
|
||||
if (offset2 == offset1) goto returnInvalid;
|
||||
name = exp.substr(offset1, offset2-offset1);
|
||||
offset1 = offset2;
|
||||
}
|
||||
m_class = name;
|
||||
// Now we have a namespace and class name.
|
||||
// The namespace might be empty.
|
||||
mangleXhpName(m_class, m_class);
|
||||
if (m_class == "error") m_class = ErrorClassName;
|
||||
if (!m_namespace.empty()) {
|
||||
m_class = m_namespace + "\\" + m_class;
|
||||
m_namespace.clear();
|
||||
}
|
||||
if (offset1 < len-2 && exp[offset1] == '@') {
|
||||
offset1++;
|
||||
m_url = exp.substr(offset1, len-offset1);
|
||||
} else {
|
||||
m_class = input;
|
||||
}
|
||||
if (strncasecmp(m_class.c_str(), "error", m_class.size()) == 0) {
|
||||
m_class = ErrorClassName;
|
||||
// check for unparsed characters at end of exp
|
||||
if (offset1 != len) goto returnInvalid;
|
||||
}
|
||||
return;
|
||||
|
||||
returnInvalid:
|
||||
m_valid = false;
|
||||
}
|
||||
|
||||
bool BreakPointInfo::MatchFile(const char *haystack, int haystack_len,
|
||||
|
||||
@@ -38,7 +38,7 @@ void CmdException::help(DebuggerClient &client) {
|
||||
client.helpTitle("Exception Command");
|
||||
client.helpCmds(
|
||||
"[e]xception {cls}", "breaks if class of exception throws",
|
||||
"[e]xception {ns}::{cls}", "breaks if class of exception throws",
|
||||
"[e]xception {ns}\{cls}", "breaks if class of exception throws",
|
||||
"[e]xception error", "breaks on errors, warnings and notices",
|
||||
"[e]xception {above}@{url}", "breaks only if url also matches",
|
||||
"", "",
|
||||
|
||||
@@ -16,4 +16,4 @@ class cls2 {
|
||||
}
|
||||
}
|
||||
|
||||
error_log('break1.inc1 loaded');
|
||||
error_log('break2.php loaded');
|
||||
|
||||
@@ -8,7 +8,7 @@ Breakpoint 3 set upon entering cls2::pubObj()
|
||||
break cls2::pubCls()
|
||||
Breakpoint 4 set upon entering cls2::pubCls()
|
||||
run
|
||||
break1.inc1 loaded
|
||||
break2.php loaded
|
||||
Program %s/break2.php exited normally.
|
||||
@ foo2('test_break6')
|
||||
Breakpoint 2 reached at foo2() on line 6 of %s/break2.php
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace TestNs;
|
||||
// Warning: line numbers are sensitive, do not change
|
||||
|
||||
function foo($x) {
|
||||
$y = $x.'_suffix';
|
||||
$y = $x.'_TestNs';
|
||||
\error_log($y);
|
||||
}
|
||||
|
||||
@@ -17,4 +17,20 @@ class cls {
|
||||
}
|
||||
}
|
||||
|
||||
namespace TestNs\Nested;
|
||||
|
||||
function foo($x) {
|
||||
$y = $x.'_TestNs\Nested';
|
||||
\error_log($y);
|
||||
}
|
||||
|
||||
class cls {
|
||||
public function pubObj($x) {
|
||||
\error_log("pubObj:".$x.'_TestNs\Nested');
|
||||
}
|
||||
public static function pubCls($x) {
|
||||
\error_log("pubCls:".$x.'_TestNs\Nested');
|
||||
}
|
||||
}
|
||||
|
||||
\error_log('break3.php loaded');
|
||||
|
||||
@@ -4,49 +4,96 @@ break3.php loaded
|
||||
Program %s/break3.php exited normally.
|
||||
break \TestNs\foo()
|
||||
Breakpoint 1 set upon entering TestNs\foo()
|
||||
@ \TestNs\foo('test_break7')
|
||||
@ \TestNs\foo('test_break1')
|
||||
Breakpoint 1 reached at TestNs\foo() on line 7 of %s/break3.php
|
||||
6 function foo($x) {
|
||||
7 $y = $x.'_suffix';
|
||||
7 $y = $x.'_TestNs';
|
||||
8 \error_log($y);
|
||||
|
||||
variable
|
||||
$x = "test_break7"
|
||||
$x = "test_break1"
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
test_break7_suffix
|
||||
test_break1_TestNs
|
||||
|
||||
break TestNs\cls::pubObj()
|
||||
Breakpoint 1 set upon entering TestNs\cls::pubObj()
|
||||
@ $break8=new \TestNs\cls()
|
||||
|
||||
@ $break8->pubObj('test_break8')
|
||||
@ $break8->pubObj('test_break2')
|
||||
Breakpoint 1 reached at TestNs\cls::pubObj() on line 13 of %s/break3.php
|
||||
12 public function pubObj($x) {
|
||||
13 \error_log("pubObj:".$x);
|
||||
14 }
|
||||
|
||||
variable
|
||||
$x = "test_break8"
|
||||
$x = "test_break2"
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
pubObj:test_break8
|
||||
pubObj:test_break2
|
||||
|
||||
break \TestNs\cls::pubCls()
|
||||
Breakpoint 1 set upon entering TestNs\cls::pubCls()
|
||||
@ \TestNs\cls::pubCls('test_break9')
|
||||
@ \TestNs\cls::pubCls('test_break3')
|
||||
Breakpoint 1 reached at TestNs\cls::pubCls() on line 16 of %s/break3.php
|
||||
15 public static function pubCls($x) {
|
||||
16 \error_log("pubCls:".$x);
|
||||
17 }
|
||||
|
||||
variable
|
||||
$x = "test_break9"
|
||||
$x = "test_break3"
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
pubCls:test_break9
|
||||
pubCls:test_break3
|
||||
|
||||
break \TestNs\Nested\foo()
|
||||
Breakpoint 1 set upon entering TestNs\Nested\foo()
|
||||
@ \TestNs\Nested\foo('test_break4')
|
||||
Breakpoint 1 reached at TestNs\Nested\foo() on line 23 of %s/break3.php
|
||||
22 function foo($x) {
|
||||
23 $y = $x.'_TestNs\Nested';
|
||||
24 \error_log($y);
|
||||
|
||||
variable
|
||||
$x = "test_break4"
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
test_break4_TestNs\Nested
|
||||
|
||||
break TestNs\Nested\cls::pubObj()
|
||||
Breakpoint 1 set upon entering TestNs\Nested\cls::pubObj()
|
||||
@ $break8=new \TestNs\Nested\cls()
|
||||
|
||||
@ $break8->pubObj('test_break5')
|
||||
Breakpoint 1 reached at TestNs\Nested\cls::pubObj() on line 29 of %s/break3.php
|
||||
28 public function pubObj($x) {
|
||||
29 \error_log("pubObj:".$x.'_TestNs\Nested');
|
||||
30 }
|
||||
|
||||
variable
|
||||
$x = "test_break5"
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
pubObj:test_break5_TestNs\Nested
|
||||
|
||||
break \TestNs\Nested\cls::pubCls()
|
||||
Breakpoint 1 set upon entering TestNs\Nested\cls::pubCls()
|
||||
@ \TestNs\Nested\cls::pubCls('test_break6')
|
||||
Breakpoint 1 reached at TestNs\Nested\cls::pubCls() on line 32 of %s/break3.php
|
||||
31 public static function pubCls($x) {
|
||||
32 \error_log("pubCls:".$x.'_TestNs\Nested');
|
||||
33 }
|
||||
|
||||
variable
|
||||
$x = "test_break6"
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
pubCls:test_break6_TestNs\Nested
|
||||
|
||||
quit
|
||||
|
||||
@@ -1,17 +1,33 @@
|
||||
continue
|
||||
break \TestNs\foo()
|
||||
@ \TestNs\foo('test_break7')
|
||||
@ \TestNs\foo('test_break1')
|
||||
variable
|
||||
break clear all
|
||||
continue
|
||||
break TestNs\cls::pubObj()
|
||||
@ $break8=new \TestNs\cls()
|
||||
@ $break8->pubObj('test_break8')
|
||||
@ $break8->pubObj('test_break2')
|
||||
variable
|
||||
break clear all
|
||||
continue
|
||||
break \TestNs\cls::pubCls()
|
||||
@ \TestNs\cls::pubCls('test_break9')
|
||||
@ \TestNs\cls::pubCls('test_break3')
|
||||
variable
|
||||
break clear all
|
||||
continue
|
||||
break \TestNs\Nested\foo()
|
||||
@ \TestNs\Nested\foo('test_break4')
|
||||
variable
|
||||
break clear all
|
||||
continue
|
||||
break TestNs\Nested\cls::pubObj()
|
||||
@ $break8=new \TestNs\Nested\cls()
|
||||
@ $break8->pubObj('test_break5')
|
||||
variable
|
||||
break clear all
|
||||
continue
|
||||
break \TestNs\Nested\cls::pubCls()
|
||||
@ \TestNs\Nested\cls::pubCls('test_break6')
|
||||
variable
|
||||
break clear all
|
||||
continue
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
// Warning: line numbers are sensitive, do not change
|
||||
|
||||
namespace {
|
||||
|
||||
class MyException extends Exception { }
|
||||
|
||||
function throw_exception() {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
function throw_myexception() {
|
||||
throw new MyException();
|
||||
}
|
||||
|
||||
function error_undefined_class() {
|
||||
$x = new NoSuchClass();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Outer {
|
||||
|
||||
class MyException extends \Exception { }
|
||||
|
||||
function throw_exception() {
|
||||
throw new \Exception();
|
||||
}
|
||||
|
||||
function throw_myexception() {
|
||||
throw new MyException();
|
||||
}
|
||||
|
||||
function error_undefined_class() {
|
||||
$x = new NoSuchClass();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Outer\Inner {
|
||||
|
||||
class MyException extends \Exception { }
|
||||
|
||||
function throw_exception() {
|
||||
throw new \Exception();
|
||||
}
|
||||
|
||||
function throw_myexception() {
|
||||
throw new MyException();
|
||||
}
|
||||
|
||||
function error_undefined_class() {
|
||||
$x = new NoSuchClass();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
Program %s/exception1.php loaded. Type '[r]un' or '[c]ontinue' to go.
|
||||
run
|
||||
Program %s/exception1.php exited normally.
|
||||
exception Exception
|
||||
Breakpoint 1 set right before throwing Exception
|
||||
@ throw_exception()
|
||||
Breakpoint 1 reached: Throwing Exception at throw_exception() on line 10 of %s/exception1.php
|
||||
9 function throw_exception() {
|
||||
10 throw new Exception();
|
||||
11 }
|
||||
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit a php exception : exception 'Exception' with message '' in %s/exception1.php:10
|
||||
Stack trace:
|
||||
#0 (1): throw_exception()
|
||||
#1 (1): include()
|
||||
#2 {main}
|
||||
exception MyException
|
||||
Breakpoint 1 set right before throwing MyException
|
||||
@ throw_myexception()
|
||||
Breakpoint 1 reached: Throwing MyException at throw_myexception() on line 14 of %s/exception1.php
|
||||
13 function throw_myexception() {
|
||||
14 throw new MyException();
|
||||
15 }
|
||||
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit a php exception : exception 'MyException' with message '' in %s/exception1.php:14
|
||||
Stack trace:
|
||||
#0 (1): throw_myexception()
|
||||
#1 (1): include()
|
||||
#2 {main}
|
||||
exception error
|
||||
Breakpoint 1 set right after an error
|
||||
@ error_undefined_class()
|
||||
Breakpoint 1 reached: An error occurred at error_undefined_class() on line 18 of %s/exception1.php
|
||||
17 function error_undefined_class() {
|
||||
18 $x = new NoSuchClass();
|
||||
19 }
|
||||
|
||||
Error Message: Class undefined: NoSuchClass
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit fatal : Class undefined: NoSuchClass
|
||||
#0 at %s/exception1.php:18]
|
||||
#1 error_undefined_class(), called at [:1]
|
||||
#2 include(), called at [:1]
|
||||
|
||||
exception Exception
|
||||
Breakpoint 1 set right before throwing Exception
|
||||
@ \Outer\throw_exception()
|
||||
Breakpoint 1 reached: Throwing Exception at Outer\throw_exception() on line 28 of %s/exception1.php
|
||||
27 function throw_exception() {
|
||||
28 throw new \Exception();
|
||||
29 }
|
||||
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit a php exception : exception 'Exception' with message '' in %s/exception1.php:28
|
||||
Stack trace:
|
||||
#0 (1): Outer\throw_exception()
|
||||
#1 (1): include()
|
||||
#2 {main}
|
||||
exception \Outer\MyException
|
||||
Breakpoint 1 set right before throwing Outer\MyException
|
||||
@ Outer\throw_myexception()
|
||||
Breakpoint 1 reached: Throwing Outer\MyException at Outer\throw_myexception() on line 32 of %s/exception1.php
|
||||
31 function throw_myexception() {
|
||||
32 throw new MyException();
|
||||
33 }
|
||||
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit a php exception : exception 'Outer\MyException' with message '' in %s/exception1.php:32
|
||||
Stack trace:
|
||||
#0 (1): Outer\throw_myexception()
|
||||
#1 (1): include()
|
||||
#2 {main}
|
||||
exception error
|
||||
Breakpoint 1 set right after an error
|
||||
@ \Outer\error_undefined_class()
|
||||
Breakpoint 1 reached: An error occurred at Outer\error_undefined_class() on line 36 of %s/exception1.php
|
||||
35 function error_undefined_class() {
|
||||
36 $x = new NoSuchClass();
|
||||
37 }
|
||||
|
||||
Error Message: Class undefined: Outer\NoSuchClass
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit fatal : Class undefined: Outer\NoSuchClass
|
||||
#0 at %s/exception1.php:36]
|
||||
#1 Outer\error_undefined_class(), called at [:1]
|
||||
#2 include(), called at [:1]
|
||||
|
||||
exception Exception
|
||||
Breakpoint 1 set right before throwing Exception
|
||||
@ \Outer\Inner\throw_exception()
|
||||
Breakpoint 1 reached: Throwing Exception at Outer\Inner\throw_exception() on line 46 of %s/exception1.php
|
||||
45 function throw_exception() {
|
||||
46 throw new \Exception();
|
||||
47 }
|
||||
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit a php exception : exception 'Exception' with message '' in %s/exception1.php:46
|
||||
Stack trace:
|
||||
#0 (1): Outer\Inner\throw_exception()
|
||||
#1 (1): include()
|
||||
#2 {main}
|
||||
exception Outer\Inner\MyException
|
||||
Breakpoint 1 set right before throwing Outer\Inner\MyException
|
||||
@ Outer\Inner\throw_myexception()
|
||||
Breakpoint 1 reached: Throwing Outer\Inner\MyException at Outer\Inner\throw_myexception() on line 50 of %s/exception1.php
|
||||
49 function throw_myexception() {
|
||||
50 throw new MyException();
|
||||
51 }
|
||||
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit a php exception : exception 'Outer\Inner\MyException' with message '' in %s/exception1.php:50
|
||||
Stack trace:
|
||||
#0 (1): Outer\Inner\throw_myexception()
|
||||
#1 (1): include()
|
||||
#2 {main}
|
||||
exception error
|
||||
Breakpoint 1 set right after an error
|
||||
@ \Outer\Inner\error_undefined_class()
|
||||
Breakpoint 1 reached: An error occurred at Outer\Inner\error_undefined_class() on line 54 of %s/exception1.php
|
||||
53 function error_undefined_class() {
|
||||
54 $x = new NoSuchClass();
|
||||
55 }
|
||||
|
||||
Error Message: Class undefined: Outer\Inner\NoSuchClass
|
||||
break clear all
|
||||
All breakpoints are cleared.
|
||||
continue
|
||||
Hit fatal : Class undefined: Outer\Inner\NoSuchClass
|
||||
#0 at %s/exception1.php:54]
|
||||
#1 Outer\Inner\error_undefined_class(), called at [:1]
|
||||
#2 include(), called at [:1]
|
||||
|
||||
quit
|
||||
@@ -0,0 +1,38 @@
|
||||
run
|
||||
exception Exception
|
||||
@ throw_exception()
|
||||
break clear all
|
||||
continue
|
||||
exception MyException
|
||||
@ throw_myexception()
|
||||
break clear all
|
||||
continue
|
||||
exception error
|
||||
@ error_undefined_class()
|
||||
break clear all
|
||||
continue
|
||||
exception Exception
|
||||
@ \Outer\throw_exception()
|
||||
break clear all
|
||||
continue
|
||||
exception \Outer\MyException
|
||||
@ Outer\throw_myexception()
|
||||
break clear all
|
||||
continue
|
||||
exception error
|
||||
@ \Outer\error_undefined_class()
|
||||
break clear all
|
||||
continue
|
||||
exception Exception
|
||||
@ \Outer\Inner\throw_exception()
|
||||
break clear all
|
||||
continue
|
||||
exception Outer\Inner\MyException
|
||||
@ Outer\Inner\throw_myexception()
|
||||
break clear all
|
||||
continue
|
||||
exception error
|
||||
@ \Outer\Inner\error_undefined_class()
|
||||
break clear all
|
||||
continue
|
||||
quit
|
||||
Referência em uma Nova Issue
Bloquear um usuário