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:
Herman Venter
2013-06-13 16:22:04 -07:00
commit de Sara Golemon
commit 4ed56d8a1d
10 arquivos alterados com 388 adições e 37 exclusões
+46 -20
Ver Arquivo
@@ -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,
+1 -1
Ver Arquivo
@@ -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",
"", "",
+1 -1
Ver Arquivo
@@ -16,4 +16,4 @@ class cls2 {
}
}
error_log('break1.inc1 loaded');
error_log('break2.php loaded');
+1 -1
Ver Arquivo
@@ -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
+17 -1
Ver Arquivo
@@ -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');
+57 -10
Ver Arquivo
@@ -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
+19 -3
Ver Arquivo
@@ -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
+57
Ver Arquivo
@@ -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
+38
Ver Arquivo
@@ -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