Merge lp:~zorba-coders/zorba/debugger_client into lp:zorba

Proposed by Gabriel Petrovay
Status: Merged
Approved by: Gabriel Petrovay
Approved revision: 10593
Merged at revision: 10588
Proposed branch: lp:~zorba-coders/zorba/debugger_client
Merge into: lp:zorba
Diff against target: 6749 lines (+3407/-2155)
47 files modified
CMakeConfiguration.txt (+7/-4)
bin/CMakeLists.txt (+21/-18)
bin/debug_client/debug_command.cpp (+0/-99)
bin/debug_client/event_handler_init.cpp.in (+0/-41)
bin/debug_client/lock_free_queue.cpp (+0/-16)
bin/debug_client/message-handler.xq (+0/-165)
bin/debugger/command.h (+164/-211)
bin/debugger/command_arg.h (+237/-0)
bin/debugger/command_line_handler.cpp (+350/-203)
bin/debugger/command_line_handler.h (+111/-58)
bin/debugger/command_prompt.cpp (+246/-0)
bin/debugger/command_prompt.h (+60/-0)
bin/debugger/config.h.cmake (+24/-0)
bin/debugger/event_handler.cpp (+82/-76)
bin/debugger/event_handler.h (+25/-12)
bin/debugger/lock_free_queue.h (+10/-2)
bin/debugger/main.cpp (+290/-14)
bin/debugger/tuple.h (+6/-0)
bin/zorbacmd.cpp (+7/-9)
cmake_modules/FindLibedit.cmake (+46/-0)
include/zorba/config.h.cmake (+8/-8)
include/zorba/debugger_client.h (+9/-1)
modules/com/zorba-xquery/www/modules/CMakeLists.txt (+7/-0)
modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq (+277/-0)
src/compiler/expression/expr.cpp (+0/-1)
src/compiler/translator/translator.cpp (+5/-7)
src/debugger/debugger_client.cpp (+0/-2)
src/debugger/debugger_clientimpl.cpp (+545/-458)
src/debugger/debugger_clientimpl.h (+16/-9)
src/debugger/debugger_common.h (+3/-10)
src/debugger/debugger_commons.cpp (+122/-24)
src/debugger/debugger_commons.h (+11/-15)
src/debugger/debugger_communicator.cpp (+3/-3)
src/debugger/debugger_communicator.h (+4/-4)
src/debugger/debugger_protocol.cpp (+28/-16)
src/debugger/debugger_runtime.cpp (+308/-87)
src/debugger/debugger_runtime.h (+29/-12)
src/debugger/debugger_server.cpp (+229/-85)
src/debugger/debugger_server.h (+15/-1)
src/debugger/socket_streambuf.cpp (+68/-55)
src/debugger/socket_streambuf.h (+20/-9)
src/unit_tests/CMakeLists.txt (+0/-6)
src/unit_tests/test_debugger_protocol.cpp (+0/-414)
test/rbkt/ExpQueryResults/zorba/debugger/dmh/break_response.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/debugger/dmh/break_response_no_info.xml.res (+1/-0)
test/rbkt/Queries/zorba/debugger/dmh/break_response.xq (+5/-0)
test/rbkt/Queries/zorba/debugger/dmh/break_response_no_info.xq (+7/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/debugger_client
Reviewer Review Type Date Requested Status
David Graf (community) Approve
Gabriel Petrovay (community) Approve
Juan Zacarias Pending
Review via email: mp+86305@code.launchpad.net

Commit message

Mature zorba debugger with graceful degradation if libedit not found.

Description of the change

Mature zorba debugger with graceful degradation if libedit not found.

To post a comment you must log in.
Revision history for this message
Gabriel Petrovay (gabipetrovay) :
review: Approve
Revision history for this message
David Graf (davidagraf) wrote :

I reviewed CMakeConfiguration.txt, bin/CMakeLists.txt, bin/debugger/config.h.cmake.

Looks good to me. I was only thinking if it would be a good idea to remove the option ZORBA_WITH_DEBUGGER_CLIENT (generating the debugger client if debugging is switched on). The less options to better.

review: Approve
Revision history for this message
Gabriel Petrovay (gabipetrovay) wrote :

Use the conversation "Can we please have libedit on the build server?" for opinions about ZORBA_WITH_DEBUGGER_CLIENT.

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

The attempt to merge lp:~zorba-coders/zorba/debugger_client into lp:zorba failed. Below is the output from the failed tests.

CMake Error at /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake:272 (message):
  Validation queue job debugger_client-2011-12-20T16-40-29.862Z is finished.
  The final status was:

  No tests were run - build or configure step must have failed.

  Not commiting changes.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

The attempt to merge lp:~zorba-coders/zorba/debugger_client into lp:zorba failed. Below is the output from the failed tests.

CMake Error at /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake:272 (message):
  Validation queue job debugger_client-2011-12-20T17-21-18.291Z is finished.
  The final status was:

  1 tests did not succeed - changes not commited.

Error in read script: /home/ceej/zo/testing/zorbatest/tester/TarmacLander.cmake

10593. By Gabriel Petrovay

added missing version and xquery version from the dbgp-message-handler.xq module

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job debugger_client-2011-12-20T18-12-16.752Z is finished. The final status was:

All tests succeeded!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeConfiguration.txt'
--- CMakeConfiguration.txt 2011-09-16 19:55:59 +0000
+++ CMakeConfiguration.txt 2011-12-20 18:15:30 +0000
@@ -70,10 +70,6 @@
70SET(ZORBA_FOR_ONE_THREAD_ONLY OFF CACHE BOOL "compile zorba for single threaded use")70SET(ZORBA_FOR_ONE_THREAD_ONLY OFF CACHE BOOL "compile zorba for single threaded use")
71MESSAGE(STATUS "ZORBA_FOR_ONE_THREAD_ONLY: " ${ZORBA_FOR_ONE_THREAD_ONLY})71MESSAGE(STATUS "ZORBA_FOR_ONE_THREAD_ONLY: " ${ZORBA_FOR_ONE_THREAD_ONLY})
7272
73# by default the zorba command line client is deactivated until it gets to a more stable and userfriendly state
74SET(ZORBA_WITH_DEBUGGER_CLIENT OFF CACHE BOOL "build and install zorbas command line debugger client")
75MESSAGE(STATUS "ZORBA_WITH_DEBUGGER_CLIENT: " ${ZORBA_WITH_DEBUGGER_CLIENT})
76
77IF (DEFINED UNIX)73IF (DEFINED UNIX)
78 IF (NOT DEFINED ZORBA_HAVE_PTHREAD_H AND NOT DEFINED ZORBA_FOR_ONE_THREAD_ONLY)74 IF (NOT DEFINED ZORBA_HAVE_PTHREAD_H AND NOT DEFINED ZORBA_FOR_ONE_THREAD_ONLY)
79 MESSAGE(FATAL_ERROR "pthread is not available")75 MESSAGE(FATAL_ERROR "pthread is not available")
@@ -93,6 +89,13 @@
93SET(ZORBA_WITH_DEBUGGER ON CACHE BOOL "compile zorba with debugger support")89SET(ZORBA_WITH_DEBUGGER ON CACHE BOOL "compile zorba with debugger support")
94MESSAGE(STATUS "ZORBA_WITH_DEBUGGER [ON/OFF]: " ${ZORBA_WITH_DEBUGGER})90MESSAGE(STATUS "ZORBA_WITH_DEBUGGER [ON/OFF]: " ${ZORBA_WITH_DEBUGGER})
9591
92SET(ZORBA_WITH_DEBUGGER_CLIENT ON CACHE BOOL "compile zorba with a command line debugger client")
93MESSAGE(STATUS "ZORBA_WITH_DEBUGGER_CLIENT [ON/OFF]: " ${ZORBA_WITH_DEBUGGER_CLIENT})
94
95IF (ZORBA_WITH_DEBUGGER_CLIENT AND NOT ZORBA_WITH_DEBUGGER)
96 MESSAGE(FATAL_ERROR "Can not build a debugger client if the debugger support is disabled. Turn on ZORBA_WITH_DEBUGGER")
97ENDIF (ZORBA_WITH_DEBUGGER_CLIENT AND NOT ZORBA_WITH_DEBUGGER)
98
96SET(ZORBA_TEST_TIMEOUT_VALUE 60 CACHE INTEGER "default test timeout value")99SET(ZORBA_TEST_TIMEOUT_VALUE 60 CACHE INTEGER "default test timeout value")
97MESSAGE(STATUS "ZORBA_TEST_TIMEOUT_VALUE: " ${ZORBA_TEST_TIMEOUT_VALUE})100MESSAGE(STATUS "ZORBA_TEST_TIMEOUT_VALUE: " ${ZORBA_TEST_TIMEOUT_VALUE})
98101
99102
=== modified file 'bin/CMakeLists.txt'
--- bin/CMakeLists.txt 2011-11-04 11:40:20 +0000
+++ bin/CMakeLists.txt 2011-12-20 18:15:30 +0000
@@ -15,26 +15,29 @@
15INCLUDE_DIRECTORIES(AFTER ${CMAKE_SOURCE_DIR}/src/)15INCLUDE_DIRECTORIES(AFTER ${CMAKE_SOURCE_DIR}/src/)
16INCLUDE_DIRECTORIES(AFTER ${CMAKE_CURRENT_SOURCE_DIR})16INCLUDE_DIRECTORIES(AFTER ${CMAKE_CURRENT_SOURCE_DIR})
1717
18IF(ZORBA_WITH_DEBUGGER_CLIENT)18IF (ZORBA_WITH_DEBUGGER_CLIENT)
19 CONFIGURE_FILE (debug_client/event_handler_init.cpp.in debug_client/event_handler_init.cpp)19 IF (NOT WIN32)
20 20 FIND_PACKAGE (Libedit)
21 SET(DEBUG_CLIENT_SRCS21 IF (LIBEDIT_FOUND)
22 debug_client/tuple.h22 INCLUDE_DIRECTORIES (${LIBEDIT_INCLUDE_DIRS})
23 debug_client/main.cpp23 SET (LIBEDIT_LIBS ${LIBEDIT_LIBRARIES})
24 debug_client/debug_command.h24 ENDIF (LIBEDIT_FOUND)
25 debug_client/debug_command.cpp25 ENDIF (NOT WIN32)
26 debug_client/command_line_handler.h26
27 debug_client/command_line_handler.cpp27 CHECK_INCLUDE_FILES ("editline/readline.h" ZORBA_HAVE_READLINE_H)
28 debug_client/lock_free_queue.h28 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/debugger/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/debugger/config.h)
29 debug_client/event_handler.h29 MESSAGE(STATUS "configured ${CMAKE_CURRENT_SOURCE_DIR}/debugger/config.h.cmake --> ${CMAKE_CURRENT_BINARY_DIR}/debugger/config.h")
30 debug_client/event_handler.cpp30 INCLUDE_DIRECTORIES (BEFORE ${CMAKE_CURRENT_BINARY_DIR}/debugger)
31 ${CMAKE_CURRENT_BINARY_DIR}/debug_client/event_handler_init.cpp31
32 SET (DEBUG_CLIENT_SRCS
33 debugger/main.cpp
34 debugger/command_prompt.cpp
35 debugger/command_line_handler.cpp
36 debugger/event_handler.cpp
32 )37 )
33 38
34 CONFIGURE_FILE (debug_client/message-handler.xq message-handler.xq)39 ZORBA_GENERATE_EXE ("xqdb" "${DEBUG_CLIENT_SRCS}" "${LIBEDIT_LIBS}" "xqdb" "bin")
35 40ENDIF (ZORBA_WITH_DEBUGGER_CLIENT)
36 ZORBA_GENERATE_EXE("debuggercmd" "${DEBUG_CLIENT_SRCS}" "" "debugger" "bin")
37ENDIF(ZORBA_WITH_DEBUGGER_CLIENT)
3841
39SET(SRCS42SET(SRCS
40 zorbacmd.cpp43 zorbacmd.cpp
4144
=== removed file 'bin/debug_client/debug_command.cpp'
--- bin/debug_client/debug_command.cpp 2011-07-01 01:53:24 +0000
+++ bin/debug_client/debug_command.cpp 1970-01-01 00:00:00 +0000
@@ -1,99 +0,0 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <iostream>
17#include "debug_client/debug_command.h"
18
19namespace zorba { namespace debugclient {
20
21
22 void CommandLine::execute()
23 {
24 for (;;) {
25 std::cout << "zdb>> ";
26 std::string command;
27 std::getline(std::cin, command);
28 std::vector<std::string> args;
29 args << command;
30 std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.find(args[0]);
31 if (lIter == theCommands.end()) {
32 std::cout << args[0] << ": Command not found" << std::endl;
33 continue;
34 }
35 if (!lIter->second->execute(args))
36 continue;
37 return;
38 }
39 }
40
41
42 CommandLine::~CommandLine()
43 {
44 for (std::map<std::string, UntypedCommand*>::iterator i = theCommands.begin();
45 i != theCommands.end(); ++i)
46 {
47 delete i->second;
48 }
49 }
50
51 CommandLine& CommandLine::operator<<(UntypedCommand *aCommand)
52 {
53 theCommands.insert(std::make_pair(aCommand->get_name(), aCommand));
54 return *this;
55 }
56}}
57
58namespace std {
59 vector<string>& operator<< (vector<string>& vec, const string& str)
60 {
61 string::size_type before = 0;
62 string::size_type pos = str.find(" ", 0);
63 while (pos != str.npos) {
64 std::string lSub = str.substr(before, pos - before);
65 if (lSub[0] == '"') {
66 std::string::size_type lBeforeCopy = before;
67 do {
68 lBeforeCopy = str.find("\"", lBeforeCopy + 1);
69 } while (pos != str.npos && str.size() > pos + 1 && str[pos + 1] == '\\');
70 pos = lBeforeCopy;
71 lSub = str.substr(before + 1, pos - before - 1);
72 }
73 vec.push_back(lSub);
74 before = pos + 1;
75 pos = str.find(" ", before);
76 }
77 std::string lSub = str.substr(before);
78 if (lSub[0] == '"') {
79 pos = str.find("\"", before + 1);
80 lSub = str.substr(before + 1, pos - before - 1);
81 }
82 vec.push_back(lSub);
83 return vec;
84 }
85
86 set<string>& operator<< (set<string>& vec, const string& str)
87 {
88 string::size_type before = 0;
89 string::size_type pos = str.find(" ", 0);
90 while (pos != str.npos) {
91 vec.insert(str.substr(before, pos));
92 before = pos + 1;
93 pos = str.find(" ", before);
94 }
95 vec.insert(str.substr(before));
96 return vec;
97 }
98
99}
1000
=== removed file 'bin/debug_client/event_handler_init.cpp.in'
--- bin/debug_client/event_handler_init.cpp.in 2011-07-01 01:53:24 +0000
+++ bin/debug_client/event_handler_init.cpp.in 1970-01-01 00:00:00 +0000
@@ -1,41 +0,0 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <fstream>
17#include "debug_client/event_handler.h"
18
19namespace zorba { namespace debugclient {
20
21 std::istream* EventHandler::getCurrentDirectory() {
22 const char* build_dir = "@CMAKE_BINARY_DIR@/bin/message-handler.xq";
23 const char* install_dir =
24#ifndef WIN32
25 "@CMAKE_INSTALL_PREFIX@/bin/";
26#else
27 "C:/Program Files/Zorba XQuery Processor @ZORBA_MAJOR_NUMBER@.@ZORBA_MINOR_NUMBER@.@ZORBA_PATCH_NUMBER@/bin/";
28#endif
29 std::auto_ptr<std::ifstream> stream(new std::ifstream(build_dir));
30 if (stream->good()) {
31 return stream.release();
32 }
33 stream.reset(new std::ifstream(install_dir));
34 if (stream->good()) {
35 return stream.release();
36 }
37 return 0;
38 }
39
40}} // end of namespace zorba::debugclient
41
420
=== removed file 'bin/debug_client/lock_free_queue.cpp'
--- bin/debug_client/lock_free_queue.cpp 2011-07-01 01:53:24 +0000
+++ bin/debug_client/lock_free_queue.cpp 1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "lock_free_queue.h"
170
=== removed file 'bin/debug_client/message-handler.xq'
--- bin/debug_client/message-handler.xq 2011-08-26 23:36:24 +0000
+++ bin/debug_client/message-handler.xq 1970-01-01 00:00:00 +0000
@@ -1,165 +0,0 @@
1(:
2 : Copyright 2006-2009 The FLWOR Foundation.
3 :
4 : Licensed under the Apache License, Version 2.0 (the "License");
5 : you may not use this file except in compliance with the License.
6 : You may obtain a copy of the License at
7 :
8 : http://www.apache.org/licenses/LICENSE-2.0
9 :
10 : Unless required by applicable law or agreed to in writing, software
11 : distributed under the License is distributed on an "AS IS" BASIS,
12 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : See the License for the specific language governing permissions and
14 : limitations under the License.
15:)
16
17import module namespace refl = 'http://www.zorba-xquery.com/modules/reflection';
18import module namespace sctx = "http://www.zorba-xquery.com/modules/introspection/sctx";
19import module namespace base64 = "http://www.zorba-xquery.com/modules/converters/base64";
20
21
22declare variable $local:localns as xs:string := 'http://www.w3.org/2005/xquery-local-functions';
23
24
25declare variable $local:endl as xs:string := '
26';
27
28declare function local:has-to-stop($resp as element())
29{
30 fn:not(($resp/@command/data(.) eq "stop" and $resp/@reason/data(.) eq "ok")
31 or ($resp/@status/data(.) eq "stopped")
32 or ($resp/@status/data(.) eq "stopping"))
33};
34
35declare function local:status($resp as element())
36{
37 fn:concat(
38 "Status: ", $resp/@status/data(.), $local:endl,
39 "Reason: ", $resp/@reason/data(.), $local:endl,
40 let $msg := $resp/text()
41 return
42 if (fn:empty($msg) or $msg eq "") then
43 ""
44 else
45 fn:concat($msg, $local:endl)
46 )
47};
48
49
50declare function local:run($resp as element()) {
51 if ($resp/@status/data(.) eq "starting") then
52 "Starting query"
53 else
54 local:status($resp)
55};
56
57declare function local:stop($resp as element())
58{
59 local:status($resp)
60};
61
62declare function local:breakpoint_set($resp as element())
63{
64 if ($resp/error) then
65 fn:concat("Error when setting a breakpoint: ", if ($resp/error/message) then $resp/error/message/text() else concat(" errcode: ", data($resp/error/@code)))
66 else
67 fn:concat("set breakpoint with id ", data($resp/@id), " and state ", data($resp/@state))
68};
69
70declare function local:breakpoint_list($resp as element())
71{
72 string-join(
73 for $b in $resp/breakpoint
74 return concat("Breakpoint ", data($b/@id), " at ", data($b/@filename), ":", data($b/@lineno), " ", data($b/@state)),
75 $local:endl
76 )
77};
78
79declare function local:breakpoint_remove($resp as element())
80{
81 "Breakpoint removed"
82};
83
84declare function local:stack_depth($resp as element())
85{
86 concat("Depth: ", data($resp/@depth))
87};
88
89declare function local:stack_get($resp as element())
90{
91 string-join(
92 for $s in $resp/stack
93 return concat("Level ", data($s/@level), " at ", data($s/@filename), ":", data($s/@lineno)),
94 $local:endl
95 )
96};
97
98
99declare function local:context_names($resp as element())
100{
101 string-join(
102 for $c in $resp/context
103 return concat("Context: ", data($c/@name), " id: ", data($c/@id)),
104 $local:endl
105 )
106};
107
108declare function local:context_get($resp as element())
109{
110 string-join(
111 for $p in $resp/property
112 return concat(data($p/@fullname), ": [", data($p/@type), "]",
113 if ($p/text() ne "") then concat(": ", base64:decode($p/text())) else ""),
114 $local:endl
115 )
116};
117
118declare function local:eval($resp as element())
119{
120 if (data($resp/@success) eq "1") then
121 local:context_get($resp)
122 else
123 concat("Eval failed", ":", $resp/error/message/text())
124};
125
126declare function local:process-response($resp as element())
127{
128 if (data($resp/@command) eq "") then
129 (fn:true(), $resp/@transaction_id/data(.), local:status($resp))
130 else
131 let $fun-cont-name := fn:QName($local:localns, concat("local:", $resp/@command/data(.), "-cont"))
132 let $fun-msg-name := fn:QName($local:localns, concat("local:", $resp/@command/data(.)))
133 return (
134 if (sctx:function-arguments-count($fun-cont-name) = 1) then
135 refl:invoke($fun-cont-name, $resp)
136 else
137 local:has-to-stop($resp),
138 $resp/@transaction_id/data(.),
139 if (sctx:function-arguments-count($fun-msg-name) = 1) then
140 refl:invoke($fun-msg-name, $resp)
141 else
142 "Recieved a message - command not implemented"
143 )
144};
145
146declare function local:process-init($init as element())
147{
148 fn:true(),
149 0,
150 fn:concat(fn:string-join(
151 ('Established connection with', $init/@language/data(.), 'client', $init/@appid/data(.)), ' '), '
152')
153};
154
155declare function local:main($response as element()) {
156 let $process-fun as xs:QName := fn:QName($local:localns, concat("local:process-", node-name($response)))
157 return
158 if (sctx:function-arguments-count($process-fun) = 1) then
159 refl:invoke($process-fun, $response)
160 else (
161 true(),
162 ($response/@transaction_id, 0)[1]/data(.),
163 "ERROR: Recieved unknown node from client"
164 )
165};
1660
=== renamed directory 'bin/debug_client' => 'bin/debugger'
=== renamed file 'bin/debug_client/debug_command.h' => 'bin/debugger/command.h'
--- bin/debug_client/debug_command.h 2011-07-04 08:05:46 +0000
+++ bin/debugger/command.h 2011-12-20 18:15:30 +0000
@@ -14,7 +14,9 @@
14 * limitations under the License.14 * limitations under the License.
15 */15 */
16#pragma once16#pragma once
17#include <zorba/config.h>17#ifndef ZORBA_DEBUGGER_COMMAND_H
18#define ZORBA_DEBUGGER_COMMAND_H
19
18#include <string>20#include <string>
19#include <vector>21#include <vector>
20#include <iostream>22#include <iostream>
@@ -23,151 +25,18 @@
23#include <sstream>25#include <sstream>
24#include <memory>26#include <memory>
25#include <typeinfo>27#include <typeinfo>
26#include "debug_client/tuple.h"28
2729#include <zorba/config.h>
28namespace zorba { namespace debugclient {30
31#include "command_arg.h"
32#include "tuple.h"
33
34
35namespace zorba { namespace debugger {
29 36
30 class DebugClientParseException : public std::exception {37 class DebugClientParseException : public std::exception {
31 };38 };
32 39
33 template<typename Tuple>
34 class CommandArg;
35
36 template<typename Tuple>
37 class CommandArgInstance {
38 public:
39 virtual int get_index() const = 0;
40 virtual const CommandArg<Tuple>* get_arg() const = 0;
41 virtual void insertValue(Tuple& t) = 0;
42 virtual bool isSet(Tuple& t) const = 0;
43 };
44
45 template<typename T, int Idx, typename Tuple>
46 class TypedCommandArgInstance : public CommandArgInstance<Tuple>
47 {
48 public:
49 TypedCommandArgInstance(T aValue, const CommandArg<Tuple>* aArg)
50 : theValue(aValue), theArg(aArg) {}
51 virtual int get_index() const { return Idx; }
52 virtual const CommandArg<Tuple>* get_arg() const { return theArg; }
53 virtual void insertValue(Tuple& t)
54 {
55 ZORBA_TR1_NS::get<Idx>(t).first = true;
56 ZORBA_TR1_NS::get<Idx>(t).second = theValue;
57 }
58 virtual bool isSet(Tuple& t) const
59 {
60 return ZORBA_TR1_NS::get<Idx>(t).first;
61 }
62 private:
63 T theValue;
64 const CommandArg<Tuple>* theArg;
65 };
66
67 template<typename Tuple>
68 class CommandArgType {
69 public:
70 virtual CommandArgInstance<Tuple>* parse(const std::string& str,
71 const CommandArg<Tuple>* arg) = 0;
72 virtual bool isVoid() const = 0;
73 virtual bool isSet(Tuple& t) const = 0;
74 virtual ~CommandArgType() {}
75 };
76
77 template<typename T, int Idx, typename Tuple>
78 class TypedCommandArgType : public CommandArgType<Tuple> {
79 public:
80 typedef T Type;
81 public: // implementation
82 TypedCommandArgType(bool aIsVoid) : theIsVoid(aIsVoid) {}
83 TypedCommandArgType(const T& aValue,
84 bool aIsVoid)
85 : theDefault(aValue), theIsVoid(aIsVoid) {}
86 virtual CommandArgInstance<Tuple>* parse(const std::string& str,
87 const CommandArg<Tuple>* arg)
88 {
89 T aValue;
90 std::stringstream stream(str);
91 stream >> aValue;
92 if (stream.fail()) {
93 std::cerr << "Could not parse argument of type "
94 << typeid(T).name()
95 << std::endl;
96 return 0;
97 }
98 return new TypedCommandArgInstance<T, Idx, Tuple>(aValue, arg);
99 }
100 virtual bool isVoid() const { return theIsVoid; }
101 virtual bool isSet(Tuple& t) const
102 {
103 return ZORBA_TR1_NS::get<Idx>(t).first;
104 }
105 private:
106 TypedCommandArgType<T, Idx, Tuple>() {}
107 T theDefault;
108 bool theIsVoid;
109 };
110
111 template<typename Tuple>
112 class CommandArg {
113 public:
114 CommandArg(unsigned aId,
115 CommandArgType<Tuple>* aType,
116 const std::set<std::string>& aFlags,
117 const std::string& aDescription,
118 bool aIsRequired)
119 : theId(aId),
120 theType(aType),
121 theFlags(aFlags),
122 theDescription(aDescription),
123 theIsRequired(aIsRequired)
124 {
125 }
126 ~CommandArg() { delete theType; }
127 unsigned get_id() const { return theId; }
128 bool canHandle(const std::string& arg) const
129 {
130 if (theFlags.find(arg) != theFlags.end()) {
131 return true;
132 }
133 return false;
134 }
135 CommandArgInstance<Tuple>* parse(const std::string& str) const
136 {
137 return theType->parse(str, this);
138 }
139 bool isVoid() const {
140 return theType->isVoid();
141 }
142 bool isRequired() const { return theIsRequired; }
143 std::string get_name() const {
144 return *(theFlags.begin());
145 }
146 bool isSet(Tuple& t) const
147 {
148 return theType->isSet(t);
149 }
150 private:
151 unsigned theId;
152 CommandArgType<Tuple>* theType;
153 std::set<std::string> theFlags;
154 std::string theDescription;
155 bool theIsRequired;
156 };
157}} // end namespace zorba
158
159namespace std {
160
161 /**
162 * This is a helper split function
163 */
164 vector<string>& operator<< (vector<string>& vec, const string& str);
165
166 set<string>& operator<< (set<string>& vec, const string& str);
167} //end namespace std
168
169namespace zorba { namespace debugclient {
170
171 template<typename Func, typename Tuple, int CommandIdx>40 template<typename Func, typename Tuple, int CommandIdx>
172 class CommandInstance41 class CommandInstance
173 {42 {
@@ -188,8 +57,10 @@
188 57
189 class UntypedCommand {58 class UntypedCommand {
190 public:59 public:
191 virtual std::string get_name() const = 0;60 virtual std::string getName() const = 0;
192 virtual std::string get_description() const = 0;61 virtual std::set<std::string> getAliases() const = 0;
62 virtual std::string getDescription() const = 0;
63 virtual void printHelp() const = 0;
193 virtual bool execute(const std::vector<std::string>& args) = 0;64 virtual bool execute(const std::vector<std::string>& args) = 0;
194 };65 };
195 66
@@ -197,77 +68,141 @@
197 class Command : public UntypedCommand {68 class Command : public UntypedCommand {
198 public:69 public:
199 Command(const std::string& aName, Func& aFunction, const std::string& aDescription)70 Command(const std::string& aName, Func& aFunction, const std::string& aDescription)
200 : theName(aName), theFunction(aFunction), theDescription(aDescription) {}71 : theName(aName), theFunction(aFunction), theDescription(aDescription)
72 {}
73
74 Command(const std::string& aName, const std::set<std::string> aAliases, Func& aFunction, const std::string& aDescription)
75 : theName(aName), theAliases(aAliases), theFunction(aFunction), theDescription(aDescription)
76 {}
77
201 ~Command();78 ~Command();
79
202 public:80 public:
203 Command& operator() (unsigned aId,81
204 const std::string& aFlags,82 void
205 CommandArgType<Tuple>* aType,83 addArgument(
206 const std::string& aDescription = "",84 unsigned aId,
207 bool isRequired = false);85 const std::string& aFlags,
208 virtual std::string get_name() const { return theName; }86 CommandArgType<Tuple>* aType,
209 virtual std::string get_description() const { return theDescription; }87 const std::string& aDescription = "",
88 bool isRequired = false);
89
90 static void
91 splitNames(
92 const std::string& names,
93 std::set<std::string>& set);
94
95 virtual std::string
96 getName() const
97 {
98 return theName;
99 }
100
101 virtual std::set<std::string> getAliases() const
102 {
103 return theAliases;
104 }
105
106 virtual std::string
107 getDescription() const
108 {
109 return theDescription;
110 }
111
112 virtual void
113 printHelp() const;
114
210 virtual bool execute(const std::vector<std::string>& args)115 virtual bool execute(const std::vector<std::string>& args)
211 {116 {
212 CommandInstance<Func, Tuple, CommandIdx> instance(theFunction, theTuple);117 CommandInstance<Func, Tuple, CommandIdx> instance(theFunction, theTuple);
213 if (instance.parseArguments(args, theArgs))118 if (instance.parseArguments(args, theArgs)) {
214 instance.execute();119 instance.execute();
215 else120 return true;
216 return false;121 }
217 return true;122 return false;
218 }123 }
219 private:124 private:
220 std::string theName;125 std::string theName;
126 std::set<std::string> theAliases;
221 Func& theFunction;127 Func& theFunction;
222 Tuple theTuple;128 Tuple theTuple;
223 std::string theDescription;129 std::string theDescription;
224 std::map<std::string, CommandArg<Tuple>* > theArgs;130 std::map<std::string, CommandArg<Tuple>*> theArgs;
225 };131 };
226 132
227 class CommandLine {133/*****************************************************************************/
228 public:134/*****************************************************************************/
229 ~CommandLine();135
230 public:136template<typename Func, typename Tuple, int CommandIdx>
231 void execute();137Command<Func, Tuple, CommandIdx>::~Command()
232 CommandLine& operator<< (UntypedCommand* aCommand);138{
233 private:139 typedef std::map<std::string, CommandArg<Tuple>*> ArgType;
234 std::map<std::string, UntypedCommand*> theCommands;140 for (typename ArgType::iterator i = theArgs.begin(); i != theArgs.end(); ++i) {
235 };141 delete i->second;
236 142 }
237 template<typename Func, typename Tuple, int CommandIdx>143}
238 Command<Func, Tuple, CommandIdx>::~Command()144
239 {145template<typename Func, typename Tuple, int CommandIdx>
240 typedef std::map<std::string, CommandArg<Tuple>* > ArgType;146void
241 for (typename ArgType::iterator i = theArgs.begin(); i != theArgs.end(); ++i) {147Command<Func, Tuple, CommandIdx>::printHelp() const
242 delete i->second;148{
243 }149 std::cout << "Purpose: " << getDescription() << std::endl;
244 }150
245 151 typename std::map<std::string, CommandArg<Tuple>*>::const_iterator lIter = theArgs.begin();
246 152 if (lIter == theArgs.end()) {
247 template<typename Func, typename Tuple, int CommandIdx>153 std::cout << "This command has no arguments." << std::endl;
248 Command<Func, Tuple, CommandIdx>& 154 std::cout << std::endl;
249 Command<Func, Tuple, CommandIdx>::operator() (unsigned aId,155 return;
250 const std::string& aFlags,156 }
251 CommandArgType<Tuple>* aType,157
252 const std::string& aDescription,158 std::cout << "Arguments:" << std::endl << std::endl;
253 bool isRequired)159 for (; lIter != theArgs.end(); ++lIter) {
254 {160 std::cout << " " << lIter->first << "\t" << lIter->second->getDescription() << std::endl;
255 std::set<std::string> args;161 }
256 args << aFlags;162 std::cout << std::endl;
257 for (std::set<std::string>::iterator i = args.begin(); i != args.end(); ++i) {163}
258 std::string toAdd = (i->size() == 1) ? "-" + *i : "--" + *i;164
259 theArgs.insert(std::make_pair(toAdd,165template<typename Func, typename Tuple, int CommandIdx>
260 new CommandArg<Tuple>(aId,166void
261 aType,167Command<Func, Tuple, CommandIdx>::splitNames(const std::string& aNames, std::set<std::string>& aSet)
262 args,168{
263 aDescription,169 std::string::size_type before = 0;
264 isRequired)170 std::string::size_type pos = aNames.find(" ", 0);
265 )171 while (pos != aNames.npos) {
266 );172 std::string lName = aNames.substr(before, pos);
267 }173 if (lName != "") {
268 return *this;174 aSet.insert(lName);
269 }175 }
270 176 before = pos + 1;
177 pos = aNames.find(" ", before);
178 }
179 std::string lName = aNames.substr(before);
180 if (lName != "") {
181 aSet.insert(lName);
182 }
183}
184
185template<typename Func, typename Tuple, int CommandIdx>
186void
187Command<Func, Tuple, CommandIdx>::addArgument(
188 unsigned aId,
189 const std::string& aFlags,
190 CommandArgType<Tuple>* aType,
191 const std::string& aDescription,
192 bool isRequired)
193{
194 std::set<std::string> lNames;
195 splitNames(aFlags, lNames);
196
197 for (std::set<std::string>::iterator i = lNames.begin(); i != lNames.end(); ++i) {
198 std::string toAdd = (i->size() == 1) ? "-" + *i : "--" + *i;
199 CommandArg<Tuple>* lArg = new CommandArg<Tuple>(aId, aType, lNames, aDescription, isRequired);
200 theArgs.insert(std::make_pair(toAdd, lArg));
201 }
202}
203
204/*****************************************************************************/
205
271 template<typename Tuple, typename T, int Idx>206 template<typename Tuple, typename T, int Idx>
272 CommandArgType<Tuple>* createArgType(Tuple t)207 CommandArgType<Tuple>* createArgType(Tuple t)
273 {208 {
@@ -290,6 +225,16 @@
290 return new Command<Func, Tuple, CommandIdx>(aName, aFunction, aDescription);225 return new Command<Func, Tuple, CommandIdx>(aName, aFunction, aDescription);
291 }226 }
292 227
228 template<int CommandIdx, typename Tuple, typename Func>
229 Command<Func, Tuple, CommandIdx>* createCommand(Tuple t,
230 const std::string& aName,
231 const std::set<std::string>& aAliases,
232 Func& aFunction,
233 const std::string& aDescription)
234 {
235 return new Command<Func, Tuple, CommandIdx>(aName, aAliases, aFunction, aDescription);
236 }
237
293 template<typename Func, typename Tuple, int CommandIdx>238 template<typename Func, typename Tuple, int CommandIdx>
294 bool CommandInstance<Func, Tuple, CommandIdx>::239 bool CommandInstance<Func, Tuple, CommandIdx>::
295 parseArguments(const std::vector<std::string>& args,240 parseArguments(const std::vector<std::string>& args,
@@ -301,29 +246,34 @@
301 for (ArgType::size_type i = 1; i < size; ++i) {246 for (ArgType::size_type i = 1; i < size; ++i) {
302 typename CArgType::const_iterator pos = aCommandArgs.find(args[i]);247 typename CArgType::const_iterator pos = aCommandArgs.find(args[i]);
303 if (pos == aCommandArgs.end()) {248 if (pos == aCommandArgs.end()) {
304 std::cerr << "Error: Unknown Argument " << args[i] << std::endl;249 std::cerr << "Error: Unknown option " << args[i] << std::endl;
305 parseError = true;250 parseError = true;
306 return false;251 return false;
307 }252 }
308 const CommandArg<Tuple>& arg = *(pos->second);253 const CommandArg<Tuple>& arg = *(pos->second);
309 if (!arg.isVoid() && args[++i][0] == '-') {
310 std::cerr << "Did not expect parameter for option " << args[i] << std::endl;
311 return false;
312 }
313 std::auto_ptr<CommandArgInstance<Tuple> > instance;254 std::auto_ptr<CommandArgInstance<Tuple> > instance;
314 if (arg.isVoid()) {255 if (arg.isVoid()) {
315 instance.reset(arg.parse("1"));256 instance.reset(arg.parse("1"));
316 } else {257 } else {
258 ++i;
259 if (i >= size) {
260 std::cerr << "Error: Missing value for argument " << args[i - 1] << std::endl;
261 parseError = true;
262 allSet = false;
263 return false;
264 }
317 instance.reset(arg.parse(args[i]));265 instance.reset(arg.parse(args[i]));
318 }266 }
319 instance->insertValue(theTuple);267 if (instance.get()) {
268 instance->insertValue(theTuple);
269 }
320 }270 }
321 bool allSet = true;271 bool allSet = true;
322 for (typename CArgType::const_iterator i = aCommandArgs.begin();272 for (typename CArgType::const_iterator i = aCommandArgs.begin();
323 i != aCommandArgs.end(); ++i)273 i != aCommandArgs.end(); ++i)
324 {274 {
325 if (i->second->isRequired() && !i->second->isSet(theTuple)) {275 if (i->second->isRequired() && !i->second->isSet(theTuple)) {
326 std::cerr << "Error: Argument " << i->second->get_name() << " not set" << std::endl;276 std::cerr << "Error: Argument -" << i->second->getName() << " not set" << std::endl;
327 allSet = false;277 allSet = false;
328 }278 }
329 }279 }
@@ -336,4 +286,7 @@
336 theFunction.template handle<CommandIdx>(this->theTuple);286 theFunction.template handle<CommandIdx>(this->theTuple);
337 }287 }
338288
339}} // end of namespace zorba::debugclient289} // namespace zorba
290} // namespace debugger
291
292#endif // ZORBA_DEBUGGER_COMMAND_H
340293
=== added file 'bin/debugger/command_arg.h'
--- bin/debugger/command_arg.h 1970-01-01 00:00:00 +0000
+++ bin/debugger/command_arg.h 2011-12-20 18:15:30 +0000
@@ -0,0 +1,237 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17#ifndef ZORBA_DEBUGGER_COMMAND_ARG_H
18#define ZORBA_DEBUGGER_COMMAND_ARG_H
19
20#include <string>
21#include <iostream>
22#include <set>
23#include <sstream>
24
25#include "tuple.h"
26
27
28namespace zorba { namespace debugger {
29
30template<typename Tuple>
31class CommandArg;
32
33template<typename Tuple>
34class CommandArgInstance {
35 public:
36 virtual int get_index() const = 0;
37 virtual const CommandArg<Tuple>* get_arg() const = 0;
38 virtual void insertValue(Tuple& t) = 0;
39 virtual bool isSet(Tuple& t) const = 0;
40};
41
42template<typename T, int Idx, typename Tuple>
43class TypedCommandArgInstance : public CommandArgInstance<Tuple>
44{
45 public:
46 TypedCommandArgInstance(T aValue, const CommandArg<Tuple>* aArg)
47 : theValue(aValue), theArg(aArg)
48 {
49 }
50
51 virtual int
52 get_index() const
53 {
54 return Idx;
55 }
56
57 virtual const CommandArg<Tuple>*
58 get_arg() const
59 {
60 return theArg;
61 }
62
63 virtual void
64 insertValue(Tuple& t)
65 {
66 ZORBA_TR1_NS::get<Idx>(t).first = true;
67 ZORBA_TR1_NS::get<Idx>(t).second = theValue;
68 }
69
70 virtual bool isSet(Tuple& t) const
71 {
72 return ZORBA_TR1_NS::get<Idx>(t).first;
73 }
74
75 private:
76
77 T theValue;
78 const CommandArg<Tuple>* theArg;
79};
80
81template<typename Tuple>
82class CommandArgType
83{
84 public:
85 virtual CommandArgInstance<Tuple>*
86 parse(
87 const std::string& str,
88 const CommandArg<Tuple>* arg) = 0;
89
90 virtual bool
91 isVoid() const = 0;
92
93 virtual bool
94 isSet(Tuple& t) const = 0;
95
96 virtual ~CommandArgType() {}
97};
98
99 template<typename T, int Idx, typename Tuple>
100 class TypedCommandArgType : public CommandArgType<Tuple> {
101 public:
102 typedef T Type;
103 public: // implementation
104 TypedCommandArgType(bool aIsVoid) : theIsVoid(aIsVoid) {}
105 TypedCommandArgType(const T& aValue,
106 bool aIsVoid)
107 : theDefault(aValue), theIsVoid(aIsVoid) {}
108 virtual CommandArgInstance<Tuple>* parse(const std::string& str,
109 const CommandArg<Tuple>* arg)
110 {
111 T aValue;
112
113 // special treatment for strings
114 // this is a double hack:
115 // - we check the type name if this starts with: class std::basic_string
116 // - we use void* in readEntireString to workaround the template type T
117 // which would otherwise complain during compilation if types and
118 // operators do not match
119 // TOSO: probably someone can find a more elegant solution
120 std::string lTypeName(typeid(T).name());
121 if (lTypeName.find("class std::basic_string") == 0) {
122 readEntireString(str, &aValue);
123 } else {
124 std::stringstream stream(str);
125 std::stringstream out;
126 stream >> aValue;
127 if (stream.fail()) {
128 std::cerr << "Error: Could not parse value \"" << str << "\" as type "
129 << typeid(T).name()
130 << std::endl;
131 return 0;
132 }
133 }
134
135 return new TypedCommandArgInstance<T, Idx, Tuple>(aValue, arg);
136 }
137 virtual bool isVoid() const { return theIsVoid; }
138 virtual bool isSet(Tuple& t) const
139 {
140 return ZORBA_TR1_NS::get<Idx>(t).first;
141 }
142 private:
143 void readEntireString(std::string aIn, void* aValue)
144 {
145 *((std::string*)aValue) = aIn;
146 }
147
148 TypedCommandArgType<T, Idx, Tuple>() {}
149 T theDefault;
150 bool theIsVoid;
151 };
152
153 template<typename Tuple>
154 class CommandArg {
155 public:
156 CommandArg(unsigned aId,
157 CommandArgType<Tuple>* aType,
158 const std::set<std::string>& aNames,
159 const std::string& aDescription,
160 bool aIsRequired)
161 : theId(aId),
162 theType(aType),
163 theNames(aNames),
164 theDescription(aDescription),
165 theIsRequired(aIsRequired)
166 {
167 }
168
169 ~CommandArg()
170 {
171 delete theType;
172 }
173
174 unsigned
175 get_id() const
176 {
177 return theId;
178 }
179
180 bool
181 canHandle(const std::string& arg) const
182 {
183 if (theNames.find(arg) != theNames.end()) {
184 return true;
185 }
186 return false;
187 }
188
189 CommandArgInstance<Tuple>*
190 parse(const std::string& str) const
191 {
192 return theType->parse(str, this);
193 }
194
195 bool
196 isVoid() const
197 {
198 return theType->isVoid();
199 }
200
201 bool
202 isRequired() const
203 {
204 return theIsRequired;
205 }
206
207 std::string
208 getName() const
209 {
210 return *(theNames.begin());
211 }
212
213 std::string
214 getDescription() const
215 {
216 return theDescription;
217 }
218
219 bool
220 isSet(Tuple& t) const
221 {
222 return theType->isSet(t);
223 }
224
225 private:
226
227 unsigned theId;
228 CommandArgType<Tuple>* theType;
229 std::set<std::string> theNames;
230 std::string theDescription;
231 bool theIsRequired;
232 };
233
234} // namespace zorba
235} // namespace debugger
236
237#endif // ZORBA_DEBUGGER_COMMAND_ARG_H
0238
=== modified file 'bin/debugger/command_line_handler.cpp'
--- bin/debug_client/command_line_handler.cpp 2011-07-01 01:53:24 +0000
+++ bin/debugger/command_line_handler.cpp 2011-12-20 18:15:30 +0000
@@ -1,4 +1,4 @@
1/*1 /*
2 * Copyright 2006-2008 The FLWOR Foundation.2 * Copyright 2006-2008 The FLWOR Foundation.
3 *3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");4 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,225 +23,372 @@
23# define msleep Sleep23# define msleep Sleep
24#endif24#endif
2525
26namespace zorba { namespace debugclient {26namespace zorba { namespace debugger {
27 27
28 using namespace ::std;
29 using namespace ::ZORBA_TR1_NS;28 using namespace ::ZORBA_TR1_NS;
30 29
31 CommandLineHandler::CommandLineHandler(unsigned short port,30CommandLineHandler::CommandLineHandler(
32 LockFreeConsumer<std::size_t>& aConsumer,31 unsigned short port,
33 LockFreeConsumer<bool>& aContinueQueue,32 LockFreeConsumer<std::size_t>& aConsumer,
34 EventHandler& aHandler,33 LockFreeConsumer<bool>& aContinueQueue,
35 CommandLine& aCommandLine)34 EventHandler& aHandler,
35 CommandPrompt& aCommandPrompt)
36 : theConsumer(aConsumer),36 : theConsumer(aConsumer),
37 theContinueQueue(aContinueQueue),37 theContinueQueue(aContinueQueue),
38 theClient(DebuggerClient::createDebuggerClient(&aHandler, port, "localhost")),38 theClient(DebuggerClient::createDebuggerClient(&aHandler, port, "localhost")),
39 theCommandLine(aCommandLine),39 theCommandLine(aCommandPrompt),
40 theQuit(false), theContinue(false), theWaitFor(0)40 theQuit(false), theTerminated(true), theContinue(false), theWaitFor(0)
41 {41 {
42 addCommands();42 addCommands();
43 }43 }
44 44
45 CommandLineHandler::~CommandLineHandler()45CommandLineHandler::~CommandLineHandler()
46 {46{
47 }47}
48 48
49 void CommandLineHandler::execute()49void
50 {50CommandLineHandler::execute()
51 theClient->accept();51{
52 std::set<std::size_t> lIdList;52 theClient->accept();
53 do {53 std::set<std::size_t> lIdList;
54 do {
55 getNextId(lIdList);
56 while (lIdList.find(theWaitFor) == lIdList.end()) {
54 getNextId(lIdList);57 getNextId(lIdList);
55 while (!theQuit && lIdList.find(theWaitFor) == lIdList.end()) {58 msleep(20);
56 getNextId(lIdList);59 }
57 msleep(20);60 bool lCanQuit;
58 }61 while (!theContinueQueue.consume(lCanQuit)) {
59 while (!theContinueQueue.consume(theQuit)) {62 msleep(20);
60 msleep(20);63 }
61 }64 if (lCanQuit) {
62 theQuit = !theQuit;65 theTerminated = true;
63 if (!theQuit) {66 }
64 theCommandLine.execute();67 theCommandLine.execute();
65 while (theContinue) {68 while (theContinue) {
66 theContinue = false;69 theContinue = false;
67 theCommandLine.execute();70 theCommandLine.execute();
68 }71 }
69 }72 } while (!theQuit);
70 } while (!theQuit);73}
71 }74
72 75void
73 void CommandLineHandler::getNextId(std::set<std::size_t>& aIdList)76CommandLineHandler::getNextId(std::set<std::size_t>& aIdList)
74 {77{
75 std::size_t result;78 std::size_t result;
76 if (theConsumer.consume(result)) {79 if (theConsumer.consume(result)) {
77 aIdList.insert(result);80 aIdList.insert(result);
78 }81 }
79 }82}
80 83
81 template<>84template<>
82 void CommandLineHandler::handle<Status>(ZORBA_TR1_NS::tuple<> &t)85void
83 {86CommandLineHandler::handle<Status>(ZORBA_TR1_NS::tuple<> &t)
84 theWaitFor = theClient->status();87{
85 }88 theWaitFor = theClient->status();
86 89}
87 template<>90
88 void CommandLineHandler::handle<Quit>(ZORBA_TR1_NS::tuple<> &t)91template<>
89 {92void
93CommandLineHandler::handle<Variables>(ZORBA_TR1_NS::tuple<> &t)
94{
95 theWaitFor = theClient->variables();
96}
97
98template<>
99void
100CommandLineHandler::handle<Quit>(ZORBA_TR1_NS::tuple<> &t)
101{
102 if (!theTerminated) {
90 bool answered = false;103 bool answered = false;
91 while (!answered) {104 while (!answered) {
92 std::cout << "Do you really want to stop debugging and exit? (y/n) ";105 std::cout << "Do you really want to stop debugging and exit? (y/n) ";
93 char answer;106 std::string lAnswer;
94 std::cin >> answer;107 std::getline(std::cin, lAnswer);
95 std::cout << std::endl;108 if (lAnswer == "y" || lAnswer == "yes") {
96 if (answer == 'y') {
97 answered = true;109 answered = true;
98 } else if (answered == 'n') {110 } else if (lAnswer == "n" || lAnswer == "no") {
99 theContinue = true;111 theContinue = true;
100 return;112 return;
101 }113 }
102 }114 }
103 theWaitFor = theClient->stop();115 }
104 theClient->quit();116 theWaitFor = theClient->stop();
105 }117 theClient->quit();
106 118 theQuit = true;
107 template<>119}
108 void CommandLineHandler::handle<Run>(ZORBA_TR1_NS::tuple<> &t)120
109 {121template<>
110 theWaitFor = theClient->run();122void
111 }123CommandLineHandler::handle<Run>(ZORBA_TR1_NS::tuple<> &t)
112 124{
113 template<>125 theTerminated = false;
114 void CommandLineHandler::handle<BreakpointSet>(std::tr1::tuple<bstring, bstring, bint> &t)126 theWaitFor = theClient->run();
115 {127}
116 DebuggerClient::BreakpointType lType = DebuggerClient::Line;128
117 bool lEnabled = true;129template<>
118 if (get<0>(t).first) {130void
119 if (get<0>(t).second == "disabled") {131CommandLineHandler::handle<BreakpointSet>(std::tr1::tuple<bstring, bstring, bint> &aTuple)
120 lEnabled = false;132{
121 }133 DebuggerClient::BreakpointType lType = DebuggerClient::Line;
122 }134 bool lEnabled = true;
123 theWaitFor = theClient->breakpoint_set(lType,135 if (get<0>(aTuple).first) {
124 lEnabled,136 if (get<0>(aTuple).second == "disabled") {
125 get<1>(t).second,137 lEnabled = false;
126 get<2>(t).second);138 }
127 }139 }
128 140 theWaitFor = theClient->breakpoint_set(lType,
129 template<>141 lEnabled,
130 void CommandLineHandler::handle<BreakpointGet>(tuple<bint> &aTuple)142 get<1>(aTuple).second,
131 {143 get<2>(aTuple).second);
132 theWaitFor = theClient->breakpoint_get(get<0>(aTuple).second);144}
133 }145
134 146template<>
135 template<>147void
136 void CommandLineHandler::handle<BreakpointDel>(tuple<bint> &aTuple)148CommandLineHandler::handle<BreakpointGet>(tuple<bint> &aTuple)
137 {149{
138 theWaitFor = theClient->breakpoint_remove(get<0>(aTuple).second);150 theWaitFor = theClient->breakpoint_get(get<0>(aTuple).second);
139 }151}
140 152
141 template<>153template<>
142 void CommandLineHandler::handle<BreakpointList>(tuple<> &t)154void
143 {155CommandLineHandler::handle<BreakpointRemove>(tuple<bint> &aTuple)
144 theWaitFor = theClient->breakpoint_list();156{
145 }157 theWaitFor = theClient->breakpoint_remove(get<0>(aTuple).second);
146 158}
147 template<>159
148 void CommandLineHandler::handle<StackDepth>(tuple<> &t)160template<>
149 {161void
150 theWaitFor = theClient->stack_depth();162CommandLineHandler::handle<BreakpointList>(tuple<> &aTuple)
151 }163{
152 164 theWaitFor = theClient->breakpoint_list();
153 template<>165}
154 void CommandLineHandler::handle<StackGet>(tuple<bint> &aTuple)166
155 {167template<>
156 if (get<0>(aTuple).first) {168void
157 theWaitFor = theClient->stack_get(get<0>(aTuple).second);169CommandLineHandler::handle<StackDepth>(tuple<> &aTuple)
158 } else {170{
159 theWaitFor = theClient->stack_get();171 theWaitFor = theClient->stack_depth();
160 }172}
161 }173
162 174template<>
163 template<>175void
164 void CommandLineHandler::handle<ContextNames>(tuple<>& aTuple)176CommandLineHandler::handle<StackGet>(tuple<bint> &aTuple)
165 {177{
166 theWaitFor = theClient->context_names();178 if (get<0>(aTuple).first) {
167 }179 theWaitFor = theClient->stack_get(get<0>(aTuple).second);
168 180 } else {
169 template<>181 theWaitFor = theClient->stack_get();
170 void CommandLineHandler::handle<ContextGet>(tuple<bint> &aTuple)182 }
171 {183}
172 if (get<0>(aTuple).first)184
173 theWaitFor = theClient->context_get(get<0>(aTuple).second);185template<>
174 else186void
175 theWaitFor = theClient->context_get();187CommandLineHandler::handle<ContextNames>(tuple<>& aTuple)
176 }188{
177 189 theWaitFor = theClient->context_names();
178 template<>190}
179 void CommandLineHandler::handle<Eval>(tuple<bstring>& aTuple)191
180 {192template<>
181 theWaitFor = theClient->eval(get<0>(aTuple).second);193void CommandLineHandler::handle<ContextGet>(tuple<bint, bint> &aTuple)
182 }194{
183 195 int lDepth = -1;
184 void CommandLineHandler::addCommands()196 int lContext = -1;
185 {197
186 theCommandLine << createCommand<Status>(tuple<>(), "status", *this,198 if (get<0>(aTuple).first) {
187 "Gets the status of the server");199 lDepth = get<0>(aTuple).second;
188 theCommandLine << createCommand<Quit>(tuple<>(), "quit", *this,200 }
189 "Stops debugging and quits the client");201 if (get<1>(aTuple).first) {
190 theCommandLine << createCommand<Run>(tuple<>(), "run", *this, "Run the Query");202 lContext = get<1>(aTuple).second;
191 {203 }
192 Command<CommandLineHandler, tuple<bstring, bstring, bint>, BreakpointSet>* lCommand =204 theWaitFor = theClient->context_get(lDepth, lContext);
193 createCommand<BreakpointSet>(tuple<bstring, bstring, bint>(), "break", *this, "Set a breakpoint");205}
194 (*lCommand)(0, "s", createArgType<tuple<bstring, bstring, bint>, std::string, 0>(tuple<bstring, bstring, bint>()),206
195 "breakpoint state (enabled or disabled - default: enabled)", false);207template<>
196 (*lCommand)(1, "f", createArgType<tuple<bstring, bstring, bint>, std::string, 1>(tuple<bstring, bstring, bint>()),208void CommandLineHandler::handle<Source>(tuple<bint, bint, bstring> &aTuple)
197 "The name of the file where to stop", true);209{
198 (*lCommand)(2, "l", createArgType<tuple<bstring, bstring, bint>, int, 2>(tuple<bstring, bstring, bint>()),210 theWaitFor = theClient->source(
199 "The line number", true);211 get<2>(aTuple).second,
200 212 get<0>(aTuple).second,
201 theCommandLine << lCommand;213 get<1>(aTuple).second);
202 }214}
203 {215
204 Command<CommandLineHandler, tuple<bint>, BreakpointGet>* lCommand216template<>
205 = createCommand<BreakpointGet>(tuple<bint>(), "binfo", *this, 217void CommandLineHandler::handle<Eval>(tuple<bstring>& aTuple)
206 "Get information about a given breakpoint");218{
207 (*lCommand)(0, "i", createArgType<tuple<bint>, int, 0>(tuple<bint>()),219 theWaitFor = theClient->eval(get<0>(aTuple).second);
208 "The id of the breakpoint", true);220}
209 221
210 theCommandLine << lCommand;222template<>
211 }223void
212 {224CommandLineHandler::handle<StepIn>(ZORBA_TR1_NS::tuple<> &t)
213 Command<CommandLineHandler, tuple<bint>, BreakpointDel>* lCommand225{
214 = createCommand<BreakpointDel>(tuple<bint>(), "bdel", *this, "Delete a breakpoint with a given id");226 theTerminated = false;
215 (*lCommand)(0, "i", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The id of the breakpoint", true);227 theWaitFor = theClient->step_into();
216 228}
217 theCommandLine << lCommand;229
218 }230template<>
219 theCommandLine << createCommand<BreakpointList>(tuple<>(), "blist", *this, "List all set breakpoints");231void
220 theCommandLine << createCommand<StackDepth>(tuple<>(), "sdepth", *this, "Get the depth of the stack");232CommandLineHandler::handle<StepOut>(ZORBA_TR1_NS::tuple<> &t)
221 {233{
222 Command<CommandLineHandler, tuple<bint>, StackGet>* lCommand234 theWaitFor = theClient->step_out();
223 = createCommand<StackGet>(tuple<bint>(), "sget", *this, "Get information about one or all stack frames");235}
224 (*lCommand)(0, "d", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The stack entry two show (show all if not provided)", false);236
225 theCommandLine << lCommand;237template<>
226 }238void
227 theCommandLine << createCommand<ContextNames>(tuple<>(), "cnames", *this, "Get the names of the avilable contexts");239CommandLineHandler::handle<StepOver>(ZORBA_TR1_NS::tuple<> &t)
228 {240{
229 Command<CommandLineHandler, tuple<bint>, ContextGet>* lCommand241 theTerminated = false;
230 = createCommand<ContextGet>(tuple<bint>(), "cget", *this, "Get a context");242 theWaitFor = theClient->step_over();
231 243}
232 (*lCommand)(0, "c", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The id of the context", false);244
233 245void
234 theCommandLine << lCommand;246CommandLineHandler::addCommands()
235 }247{
236 {248 typedef tuple<> TUPLE;
237 Command<CommandLineHandler, tuple<bstring>, Eval>* lCommand249 typedef tuple<bint> TUPLE_INT;
238 = createCommand<Eval>(tuple<bstring>(), "eval", *this, "Evaluate a function");250 typedef tuple<bstring> TUPLE_STR;
239 251 typedef tuple<bint, bint> TUPLE_INT_INT;
240 (*lCommand)(0, "c", createArgType<tuple<bstring>, std::string, 0>(tuple<bstring>()), "The command to evaluate", true);252 typedef tuple<bstring, bstring, bint> TUPLE_STR_STR_INT;
241 253 typedef tuple<bint, bint, bstring> TUPLE_INT_INT_STR;
242 theCommandLine << lCommand;254
243 }255 // DBGP: status
244 }256 theCommandLine << createCommand<Status>(TUPLE(), "status", *this, "Gets the status of the server");
245 257
246}} // namespace zorba::debugclient258 // ALIAS: variables (context_get -c -1)
247259 {
260 std::set<std::string> lAliases;
261 lAliases.insert("vars");
262 theCommandLine << createCommand<Variables>(TUPLE(), "variables", lAliases, *this, "Gets the variables visible in the current scope");
263 }
264
265 // META: quit
266 theCommandLine << createCommand<Quit>(TUPLE(), "quit", *this, "Stops debugging and quits the client");
267
268 // DBGP: run
269 theCommandLine << createCommand<Run>(TUPLE(), "run", *this, "Run the query");
270
271 // DBGP: breakpoint_set
272 {
273 std::set<std::string> lAliases;
274 lAliases.insert("break");
275 Command<CommandLineHandler, TUPLE_STR_STR_INT, BreakpointSet>* lCommand =
276 createCommand<BreakpointSet>(TUPLE_STR_STR_INT(), "bset", lAliases, *this, "Set a breakpoint");
277
278 lCommand->addArgument(0, "s", createArgType<TUPLE_STR_STR_INT, std::string, 0>(TUPLE_STR_STR_INT()), "breakpoint state (optional, 'enabled' or 'disabled', default: enabled)", false);
279 lCommand->addArgument(1, "f", createArgType<TUPLE_STR_STR_INT, std::string, 1>(TUPLE_STR_STR_INT()), "name of the file where to stop", true);
280 lCommand->addArgument(2, "l", createArgType<TUPLE_STR_STR_INT, int, 2>(TUPLE_STR_STR_INT()), "line number", true);
281
282 theCommandLine << lCommand;
283 }
284
285 // DBGP: breakpoint_get
286 {
287 Command<CommandLineHandler, TUPLE_INT, BreakpointGet>* lCommand =
288 createCommand<BreakpointGet>(TUPLE_INT(), "bget", *this, "Get information about a given breakpoint");
289
290 lCommand->addArgument(0, "d", createArgType<TUPLE_INT, int, 0>(TUPLE_INT()), "breakpoint ID", true);
291
292 theCommandLine << lCommand;
293 }
294
295 // DBGP: breakpoint_remove
296 {
297 std::set<std::string> lAliases;
298 lAliases.insert("clear");
299 lAliases.insert("delete");
300 Command<CommandLineHandler, TUPLE_INT, BreakpointRemove>* lCommand =
301 createCommand<BreakpointRemove>(TUPLE_INT(), "bremove", lAliases, *this, "Delete a breakpoint");
302
303 lCommand->addArgument(0, "d", createArgType<TUPLE_INT, int, 0>(TUPLE_INT()), "breakpoint ID", true);
304
305 theCommandLine << lCommand;
306 }
307
308 // DBGP: breakpoint_list
309 theCommandLine << createCommand<BreakpointList>(TUPLE(), "blist", *this, "List all set breakpoints");
310
311 // DBGP: stack_depth
312 theCommandLine << createCommand<StackDepth>(TUPLE(), "sdepth", *this, "Get the depth of the stack");
313
314 // DBGP: stack_get
315 {
316 Command<CommandLineHandler, TUPLE_INT, StackGet>* lCommand =
317 createCommand<StackGet>(TUPLE_INT(), "sget", *this, "Get information about one or all stack frames");
318
319 lCommand->addArgument(0, "d", createArgType<TUPLE_INT, int, 0>(TUPLE_INT()), "stack frame to show: 0 for current stack frame, N for the main module (optional, all frames are shown if not provided)", false);
320
321 theCommandLine << lCommand;
322 }
323
324 // DBGP: context_names
325 theCommandLine << createCommand<ContextNames>(tuple<>(), "cnames", *this, "Get the names of the avilable contexts");
326 // the DBGP -d arguments for this command is omitted since we always have/return: 0 - Local, 1 - Global
327
328 // DBGP: context_get
329 {
330 Command<CommandLineHandler, TUPLE_INT_INT, ContextGet>* lCommand =
331 createCommand<ContextGet>(TUPLE_INT_INT(), "cget", *this, "Get a context (list variables in this context)");
332
333 lCommand->addArgument(0, "d", createArgType<TUPLE_INT_INT, int, 0>(TUPLE_INT_INT()), "stack depth (optional, default: 0)", false);
334 lCommand->addArgument(0, "c", createArgType<TUPLE_INT_INT, int, 1>(TUPLE_INT_INT()), "context ID: 0 for Local, 1 for Global (optional, default: 0)", false);
335
336 theCommandLine << lCommand;
337 }
338
339 // DBGP: source
340 {
341 std::set<std::string> lAliases;
342 lAliases.insert("list");
343 Command<CommandLineHandler, TUPLE_INT_INT_STR, Source>* lCommand =
344 createCommand<Source>(TUPLE_INT_INT_STR(), "source", lAliases, *this, "List source code");
345
346 lCommand->addArgument(0, "b", createArgType<TUPLE_INT_INT_STR, int, 0>(TUPLE_INT_INT_STR()), "begin line (optional, default: first line)", false);
347 lCommand->addArgument(1, "e", createArgType<TUPLE_INT_INT_STR, int, 1>(TUPLE_INT_INT_STR()), "end line (optional, default: last line)", false);
348 lCommand->addArgument(2, "f", createArgType<TUPLE_INT_INT_STR, std::string, 2>(TUPLE_INT_INT_STR()), "file URI (optional, default: the file in the top-most stack frame during execution, main module otherwise)", false);
349
350 theCommandLine << lCommand;
351 }
352
353 // DBGP: eval
354 {
355 std::set<std::string> lAliases;
356 lAliases.insert("print");
357 Command<CommandLineHandler, TUPLE_STR, Eval>* lCommand =
358 createCommand<Eval>(TUPLE_STR(), "eval", lAliases, *this, "Evaluate an expression");
359
360 // TODO: this argument should not be here at all. Eval has the form: eval -i transaction_id -- {DATA}
361 // Eval should be called with a command like: eval 1 + 3
362 // - no need for an argument name
363 // - everything following the fist contiguous set of whitespaces are sent as string
364 lCommand->addArgument(0, "c", createArgType<TUPLE_STR, std::string, 0>(TUPLE_STR()), "expression to evaluate", true);
365
366 theCommandLine << lCommand;
367 }
368
369 // DBGP: step_in
370 {
371 std::set<std::string> lAliases;
372 lAliases.insert("step");
373 lAliases.insert("s");
374 theCommandLine << createCommand<StepIn>(TUPLE(), "in", lAliases, *this, "Step in");
375 }
376
377 // DBGP: step_out
378 {
379 std::set<std::string> lAliases;
380 lAliases.insert("finish");
381 theCommandLine << createCommand<StepOut>(TUPLE(), "out", lAliases, *this, "Step out");
382 }
383
384 // DBGP: step_over
385 {
386 std::set<std::string> lAliases;
387 lAliases.insert("next");
388 lAliases.insert("n");
389 theCommandLine << createCommand<StepOver>(TUPLE(), "over", lAliases, *this, "Step over");
390 }
391}
392
393} // namespace zorba
394} // namespace debugger
248395
=== modified file 'bin/debugger/command_line_handler.h'
--- bin/debug_client/command_line_handler.h 2011-07-01 01:53:24 +0000
+++ bin/debugger/command_line_handler.h 2011-12-20 18:15:30 +0000
@@ -14,46 +14,69 @@
14 * limitations under the License.14 * limitations under the License.
15 */15 */
16#pragma once16#pragma once
17#ifndef ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H
18#define ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H
1719
18#include <set>20#include <set>
19#include <cassert>21#include <cassert>
22
20#include <zorba/debugger_client.h>23#include <zorba/debugger_client.h>
21#include "debug_command.h"24
25#include "command.h"
26#include "command_prompt.h"
22#include "event_handler.h"27#include "event_handler.h"
2328
24namespace zorba { namespace debugclient {29
25 30namespace zorba { namespace debugger {
31
26 enum Commands {32 enum Commands {
27 Status,33 Status,
34 Variables,
35 Quit,
28 Run,36 Run,
29 BreakpointSet,37 BreakpointSet,
30 BreakpointGet,38 BreakpointGet,
31 BreakpointDel,39 BreakpointRemove,
32 BreakpointList,40 BreakpointList,
33 StackDepth,41 StackDepth,
34 StackGet,42 StackGet,
35 ContextNames,43 ContextNames,
36 ContextGet,44 ContextGet,
45 Source,
37 Eval,46 Eval,
38 Quit47 StepIn,
48 StepOut,
49 StepOver
39 };50 };
40 51
41 class CommandLineHandler {52class CommandLineHandler
53{
42 private:54 private:
55
43 typedef std::pair<bool, std::string> bstring;56 typedef std::pair<bool, std::string> bstring;
44 typedef std::pair<bool, int> bint;57 typedef std::pair<bool, int> bint;
58
45 public:59 public:
46 CommandLineHandler(unsigned short port,60
47 LockFreeConsumer<std::size_t>& aConsumer,61 CommandLineHandler(
48 LockFreeConsumer<bool>& aContinueQueue,62 unsigned short port,
49 EventHandler& aHandler,63 LockFreeConsumer<std::size_t>& aConsumer,
50 CommandLine& aCommandLine);64 LockFreeConsumer<bool>& aContinueQueue,
65 EventHandler& aHandler,
66 CommandPrompt& aCommandPrompt);
67
51 ~CommandLineHandler();68 ~CommandLineHandler();
69
52 public:70 public:
53 void execute();71 void execute();
72
54 public: // Handlers73 public: // Handlers
74
55 template<int>75 template<int>
56 void handle(ZORBA_TR1_NS::tuple<>& aTuple) { assert(false); }76 void handle(ZORBA_TR1_NS::tuple<>& aTuple)
77 {
78 assert(false);
79 }
57 80
58 template<int>81 template<int>
59 void handle(ZORBA_TR1_NS::tuple<bstring, bstring, bint>& t)82 void handle(ZORBA_TR1_NS::tuple<bstring, bstring, bint>& t)
@@ -62,63 +85,93 @@
62 }85 }
63 86
64 template<int>87 template<int>
88 void handle(ZORBA_TR1_NS::tuple<bint, bint, bstring>& t)
89 {
90 assert(false);
91 }
92
93 template<int>
65 void handle(ZORBA_TR1_NS::tuple<bint>& aTuple)94 void handle(ZORBA_TR1_NS::tuple<bint>& aTuple)
66 {95 {
67 assert(false);96 assert(false);
68 }97 }
69 98
70 template<int>99 template<int>
100 void handle(ZORBA_TR1_NS::tuple<bint, bint>& aTuple)
101 {
102 assert(false);
103 }
104
105 template<int>
71 void handle(ZORBA_TR1_NS::tuple<bstring>& aTuple)106 void handle(ZORBA_TR1_NS::tuple<bstring>& aTuple)
72 {107 {
73 assert(false);108 assert(false);
74 }109 }
110
75 private:111 private:
76 LockFreeConsumer<std::size_t>& theConsumer;112 LockFreeConsumer<std::size_t>& theConsumer;
77 LockFreeConsumer<bool>& theContinueQueue;113 LockFreeConsumer<bool>& theContinueQueue;
78 DebuggerClient* theClient;114 DebuggerClient* theClient;
79 CommandLine& theCommandLine;115 CommandPrompt& theCommandLine;
80 bool theQuit;116 bool theQuit;
81 bool theContinue;117 bool theTerminated;
82 std::size_t theWaitFor;118 bool theContinue;
119 std::size_t theWaitFor;
120
83 private:121 private:
84 void getNextId(std::set<std::size_t>& aIdList);122 void getNextId(std::set<std::size_t>& aIdList);
85 void addCommands();123 void addCommands();
86 };124};
87 125
88 template<>126template<>
89 void CommandLineHandler::handle<Status> (ZORBA_TR1_NS::tuple<>& t);127void CommandLineHandler::handle<Status> (ZORBA_TR1_NS::tuple<>& t);
90 128
91 template<>129template<>
92 void CommandLineHandler::handle<Quit> (ZORBA_TR1_NS::tuple<>& t);130void CommandLineHandler::handle<Quit> (ZORBA_TR1_NS::tuple<>& t);
93 131
94 template<>132template<>
95 void CommandLineHandler::handle<Run> (ZORBA_TR1_NS::tuple<> &t);133void CommandLineHandler::handle<Run> (ZORBA_TR1_NS::tuple<> &t);
96 134
97 template<>135template<>
98 void CommandLineHandler::handle<StackDepth> (ZORBA_TR1_NS::tuple<>& t);136void CommandLineHandler::handle<StackDepth> (ZORBA_TR1_NS::tuple<>& t);
99 137
100 template<>138template<>
101 void CommandLineHandler::handle<BreakpointList> (ZORBA_TR1_NS::tuple<>& aTuple);139void CommandLineHandler::handle<BreakpointList> (ZORBA_TR1_NS::tuple<>& aTuple);
102 140
103 template<>141template<>
104 void CommandLineHandler::handle<BreakpointSet> (ZORBA_TR1_NS::tuple<bstring, bstring, bint> &t);142void CommandLineHandler::handle<BreakpointSet> (ZORBA_TR1_NS::tuple<bstring, bstring, bint> &t);
105 143
106 template<>144template<>
107 void CommandLineHandler::handle<BreakpointGet> (ZORBA_TR1_NS::tuple<bint>& aTuple);145void CommandLineHandler::handle<BreakpointGet> (ZORBA_TR1_NS::tuple<bint>& aTuple);
108 146
109 template<>147template<>
110 void CommandLineHandler::handle<BreakpointDel>(ZORBA_TR1_NS::tuple<bint> &aTuple);148void CommandLineHandler::handle<BreakpointRemove>(ZORBA_TR1_NS::tuple<bint> &aTuple);
111 149
112 template<>150template<>
113 void CommandLineHandler::handle<StackGet> (ZORBA_TR1_NS::tuple<bint>& aTuple);151void CommandLineHandler::handle<StackGet> (ZORBA_TR1_NS::tuple<bint>& aTuple);
114 152
115 template<>153template<>
116 void CommandLineHandler::handle<ContextNames>(ZORBA_TR1_NS::tuple<> &aTuple);154void CommandLineHandler::handle<ContextNames>(ZORBA_TR1_NS::tuple<> &aTuple);
117 155
118 template<>156template<>
119 void CommandLineHandler::handle<ContextGet>(ZORBA_TR1_NS::tuple<bint> &aTuple);157void CommandLineHandler::handle<ContextGet>(ZORBA_TR1_NS::tuple<bint, bint> &aTuple);
120 158
121 template<>159template<>
122 void CommandLineHandler::handle<Eval>(ZORBA_TR1_NS::tuple<bstring>& aTuple);160void CommandLineHandler::handle<Source>(ZORBA_TR1_NS::tuple<bint, bint, bstring> &aTuple);
123 161
124}} // close namespaces zorba::debugclient162template<>
163void CommandLineHandler::handle<Eval>(ZORBA_TR1_NS::tuple<bstring>& aTuple);
164
165template<>
166void CommandLineHandler::handle<StepIn> (ZORBA_TR1_NS::tuple<> &t);
167
168template<>
169void CommandLineHandler::handle<StepOut> (ZORBA_TR1_NS::tuple<> &t);
170
171template<>
172void CommandLineHandler::handle<StepOver> (ZORBA_TR1_NS::tuple<> &t);
173
174} // namespace zorba
175} // namespace debugger
176
177#endif // ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H
125178
=== added file 'bin/debugger/command_prompt.cpp'
--- bin/debugger/command_prompt.cpp 1970-01-01 00:00:00 +0000
+++ bin/debugger/command_prompt.cpp 2011-12-20 18:15:30 +0000
@@ -0,0 +1,246 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "command_prompt.h"
17
18#include <string>
19#include <vector>
20#include <map>
21#include <iostream>
22
23#include "config.h"
24
25#ifdef ZORBA_HAVE_READLINE_H
26# include <editline/readline.h>
27#endif
28
29#include "command.h"
30
31
32namespace zorba { namespace debugger {
33
34CommandPrompt::~CommandPrompt()
35{
36 std::map<std::string, UntypedCommand*>::iterator lIter;
37 for (lIter = theCommands.begin(); lIter != theCommands.end(); ++lIter) {
38 delete lIter->second;
39 }
40}
41
42void
43CommandPrompt::printHelp(UntypedCommand* aCommand)
44{
45 // if no command is provided, print all the available commands
46 if (!aCommand) {
47 std::cout << "Available commands:" << std::endl;
48
49 // print the names of all commands
50 std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.begin();
51 while (lIter != theCommands.end()) {
52 std::cout << " " << (*lIter).first;
53 std::set<std::string> lAliases = (*lIter).second->getAliases();
54 std::set<std::string>::const_iterator lAliasIter = lAliases.begin();
55 while (lAliasIter != lAliases.end()) {
56 std::cout << ", " << *lAliasIter;
57 lAliasIter++;
58 }
59 std::cout << std::endl;
60 lIter++;
61 }
62
63 // some hints for detailed help
64 std::cout << std::endl;
65 std::cout << "Type help <command> to get more information about one command." << std::endl;
66 std::cout << std::endl;
67 } else {
68 // ok, so we have a command; then print the help
69 aCommand->printHelp();
70 }
71}
72
73void
74CommandPrompt::execute()
75{
76 for (;;) {
77#ifdef ZORBA_HAVE_READLINE_H
78 std::string lCommandLine(readline("(xqdb) "));
79#else
80 std::cout << "(xqdb) ";
81 std::string lCommandLine;
82 std::getline(std::cin, lCommandLine);
83#endif
84 std::vector<std::string> lArgs;
85
86 // split the command into arguments
87 parseLine(lCommandLine, lArgs);
88 std::string::size_type lSize = lArgs.size();
89
90 // empty command? do nothing!
91 if (lSize == 0) {
92 lArgs = theLastArgs;
93 if (lArgs.size() == 0) {
94 continue;
95 }
96 }
97 theLastArgs = lArgs;
98
99 UntypedCommand* lCommand = NULL;
100
101 // help is not a command but a hook here
102 if (lArgs.at(0) == "h" || lArgs.at(0) == "help") {
103 std::string lCmd = "";
104
105 // if the user needs the help for a specific command
106 if (lSize > 1) {
107 // do nothing if we don't have a command starting with this prefix?
108 // findCommand will print the appropriate errors
109 if (!findCommand(lArgs[1], lCommand)) {
110 continue;
111 }
112 }
113 printHelp(lCommand);
114 continue;
115 }
116 if (findCommand(lArgs[0], lCommand) && lCommand->execute(lArgs)) {
117 return;
118 }
119 continue;
120 }
121}
122
123CommandPrompt&
124CommandPrompt::operator<<(UntypedCommand *aCommand)
125{
126 theCommands.insert(std::make_pair(aCommand->getName(), aCommand));
127 return *this;
128}
129
130bool
131CommandPrompt::findCommand(const std::string& aPrefix, UntypedCommand*& aCommand)
132{
133 std::vector<UntypedCommand*> lFoundCommands;
134
135 std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.begin();
136 while (lIter != theCommands.end()) {
137 // if a command name is equal with the prefix, this is the command we want
138 if ((*lIter).first == aPrefix) {
139 aCommand = (*lIter).second;
140 return true;
141 }
142
143 bool lIsCandidate = false;
144
145 // add this command to candidate commands if the prefix matches
146 if ((*lIter).first.find(aPrefix) == 0) {
147 lFoundCommands.push_back((*lIter).second);
148 lIsCandidate = true;
149 }
150
151 // now process the aliases
152 std::set<std::string> lAliases = (*lIter).second->getAliases();
153 std::set<std::string>::const_iterator lAliasIter = lAliases.begin();
154 while (lAliasIter != lAliases.end()) {
155 // if a command alias is equal with the prefix, this is the command we want
156 if (*lAliasIter == aPrefix) {
157 aCommand = (*lIter).second;
158 return true;
159 }
160
161 // add this command to candidate commands if the prefix matches one alias
162 // and if the command is not already added
163 if (!lIsCandidate && (*lAliasIter).find(aPrefix) == 0) {
164 lFoundCommands.push_back((*lIter).second);
165 break;
166 }
167 lAliasIter++;
168 }
169
170 lIter++;
171 }
172
173 if (lFoundCommands.empty()) {
174 std::cout << "Command not found: " << aPrefix << std::endl;
175 return false;
176 }
177
178 if (lFoundCommands.size() > 1) {
179 std::cout << "Ambigous command: " << aPrefix << std::endl;
180 // show all possible commands that start with this prefix
181 for (std::string::size_type i = 0; i < lFoundCommands.size(); i++) {
182 UntypedCommand* lCommand = lFoundCommands.at(i);
183
184 // commands
185 if (lCommand->getName().find(aPrefix) == 0) {
186 std::cout << " " << lCommand->getName() << std::endl;
187 }
188
189 // and aliases
190 std::set<std::string> lAliases = lCommand->getAliases();
191 std::set<std::string>::const_iterator lAliasIter = lAliases.begin();
192 while (lAliasIter != lAliases.end()) {
193 if ((*lAliasIter).find(aPrefix) == 0) {
194 std::cout << " " << *lAliasIter << std::endl;
195 }
196 lAliasIter++;
197 }
198 }
199 return false;
200 }
201
202 aCommand = lFoundCommands[0];
203 return true;
204}
205
206void
207CommandPrompt::parseLine(const std::string& aLine, std::vector<std::string>& aVector)
208{
209 std::string::size_type lBefore = 0;
210 std::string::size_type lPos = aLine.find_first_of(" \t", 0);
211
212 while (lPos != aLine.npos) {
213 std::string lSub = aLine.substr(lBefore, lPos - lBefore);
214
215 // if two consecutive spaces, you get an empty string here
216 if (lSub != "") {
217 if (lSub[0] == '"') {
218 std::string::size_type lBeforeCopy = lBefore;
219 do {
220 lBeforeCopy = aLine.find("\"", lBeforeCopy + 1);
221 } while (lPos != aLine.npos && aLine.size() > lPos + 1 && aLine[lPos + 1] == '\\');
222 lPos = lBeforeCopy;
223 lSub = aLine.substr(lBefore + 1, lPos - lBefore - 1);
224 }
225 aVector.push_back(lSub);
226 }
227
228 lBefore = lPos + 1;
229 lPos = aLine.find_first_of(" \t", lBefore);
230 }
231 std::string lSub = aLine.substr(lBefore);
232
233 // catching the case when the command ends with a space
234 if (lSub == "") {
235 return;
236 }
237
238 if (lSub[0] == '"') {
239 lPos = aLine.find("\"", lBefore + 1);
240 lSub = aLine.substr(lBefore + 1, lPos - lBefore - 1);
241 }
242 aVector.push_back(lSub);
243}
244
245} // namespace zorba
246} // namespace debugger
0247
=== added file 'bin/debugger/command_prompt.h'
--- bin/debugger/command_prompt.h 1970-01-01 00:00:00 +0000
+++ bin/debugger/command_prompt.h 2011-12-20 18:15:30 +0000
@@ -0,0 +1,60 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17#ifndef ZORBA_DEBUGGER_COMMAND_PROMPT_H
18#define ZORBA_DEBUGGER_COMMAND_PROMPT_H
19
20#include <string>
21#include <map>
22#include <vector>
23
24
25namespace zorba { namespace debugger {
26
27class UntypedCommand;
28
29class CommandPrompt
30{
31 public:
32 ~CommandPrompt();
33
34 public:
35
36 void execute();
37
38 CommandPrompt& operator<< (UntypedCommand* command);
39
40 private:
41
42 void
43 printHelp(UntypedCommand* command);
44
45 bool
46 findCommand(const std::string& prefix, UntypedCommand*& command);
47
48 void
49 parseLine(const std::string& line, std::vector<std::string>& vector);
50
51 private:
52 std::map<std::string, UntypedCommand*> theCommands;
53 std::vector<std::string> theLastArgs;
54};
55
56
57} // namespace zorba
58} // namespace debugger
59
60#endif // ZORBA_DEBUGGER_COMMAND_PROMPT_H
061
=== added file 'bin/debugger/config.h.cmake'
--- bin/debugger/config.h.cmake 1970-01-01 00:00:00 +0000
+++ bin/debugger/config.h.cmake 2011-12-20 18:15:30 +0000
@@ -0,0 +1,24 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// This header is configured by Zorba's build process -- DO NOT EDIT!
18
19#ifndef ZORBA_DEBUGGER_CONFIG_H
20#define ZORBA_DEBUGGER_CONFIG_H
21
22#cmakedefine ZORBA_HAVE_READLINE_H
23
24#endif /* ZORBA_DEBUGGER_CONFIG_H */
025
=== modified file 'bin/debugger/event_handler.cpp'
--- bin/debug_client/event_handler.cpp 2011-07-01 01:53:24 +0000
+++ bin/debugger/event_handler.cpp 2011-12-20 18:15:30 +0000
@@ -13,88 +13,94 @@
13 * See the License for the specific language governing permissions and13 * See the License for the specific language governing permissions and
14 * limitations under the License.14 * limitations under the License.
15 */15 */
16
17#include "event_handler.h"
18
19#include <sstream>
20
16#include <zorba/zorba.h>21#include <zorba/zorba.h>
17#include <zorba/store_manager.h>22#include <zorba/store_manager.h>
18#include <zorba/iterator.h>23#include <zorba/iterator.h>
19#include <sstream>
20#include "debug_client/event_handler.h"
2124
22namespace zorba { namespace debugclient {25namespace zorba { namespace debugger {
23 26
24 EventHandler::EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContProducer)27EventHandler::EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContProducer)
25 : theIdQueue(aQueue), theContinueProducer(aContProducer),28 : theIdQueue(aQueue), theContinueProducer(aContProducer),
26 theStore(StoreManager::getStore()),29 theStore(StoreManager::getStore()),
27 theZorbaInstance(Zorba::getInstance(theStore)),30 theZorbaInstance(Zorba::getInstance(theStore)),
28 theStaticContext(theZorbaInstance->createStaticContext())31 theStaticContext(theZorbaInstance->createStaticContext())
29 32{
30 {33}
31 try {34
32 Zorba_CompilerHints_t lHints;35EventHandler::~EventHandler()
33 lHints.opt_level = ZORBA_OPT_LEVEL_O1;36{
34 std::auto_ptr<std::istream> stream(getCurrentDirectory());37 theStaticContext = 0;
35 zorba::String query;38 theZorbaInstance->shutdown();
36 char buffer[1024];39 StoreManager::shutdownStore(theStore);
37 std::string::size_type s;40}
38 while ((s = stream->readsome(buffer, 1024))) {41
39 query.append(std::string(buffer, s));42void
40 }43EventHandler::init()
41 theStaticContext->loadProlog(query, lHints);44{
42 } catch (zorba::ZorbaException& e) {45 try {
43 std::cerr << "Exception: I was not able to load the query file:" << std::endl;46 Zorba_CompilerHints_t lHints;
44 std::cerr << e.what() << std::endl;47 lHints.opt_level = ZORBA_OPT_LEVEL_O1;
45 throw;48 zorba::String lProlog("import module namespace dmh = 'http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler';");
46 }49 theStaticContext->loadProlog(lProlog, lHints);
47 }50 } catch (zorba::ZorbaException& e) {
48 51 std::cerr << "Exception: I was not able to load the query file:" << std::endl;
49 EventHandler::~EventHandler()52 std::cerr << e.what() << std::endl;
50 {53 throw;
51 theStaticContext = 0;54 }
52 theZorbaInstance->shutdown();55}
53 StoreManager::shutdownStore(theStore);56
54 }57void
55 58EventHandler::parseMessage(const std::string &aMessage)
56 void EventHandler::parseMessage(const std::string &aMessage)59{
57 {60 try {
58 try {61#ifndef NDEBUG
59 zorba::String queryString = "local:main(";62 // uncomment this to see the raw messages received by the event handler
60 queryString += aMessage + ")";63 //std::cout << "Processing response: " << aMessage << std::endl;
61 XQuery_t query = theZorbaInstance->compileQuery(queryString, theStaticContext);64#endif
62 Iterator_t lIter = query->iterator();65 // the query to process the response
63 Item item;66 std::stringstream lQueryStream;
64 lIter->open();67 lQueryStream << "dmh:process(" << aMessage << ")";
65 bool doContinue = false;68 XQuery_t lQuery = theZorbaInstance->compileQuery(lQueryStream.str(), theStaticContext);
66 lIter->next(item);69
67 {70 // get the query result sequrence:
68 const std::string& continueString = item.getStringValue().str();71 // 1. a message
69 if (continueString == "true") {72 Iterator_t lIter = lQuery->iterator();
70 doContinue = true;73 Item lItem;
71 } else if (continueString == "false") {74 lIter->open();
72 doContinue = false;75 lIter->next(lItem);
73 } else {76 std::size_t lId;
74 std::stringstream stream(continueString);77 std::stringstream lStream(lItem.getStringValue().c_str());
75 stream >> doContinue;78 lStream >> lId;
76 }79
77 }80 // 2. an "idle" flag (to disable quit confirmation)
78 lIter->next(item);81 bool lCanQuit = false;
79 std::size_t lId;82 if (lIter->next(lItem)) {
80 {83 String lMessage = lItem.getStringValue();
81 std::stringstream stream(item.getStringValue().c_str());84 lCanQuit = lMessage == "idle";
82 stream >> lId;85 std::cout << std::endl << lItem.getStringValue() << std::endl;
83 }86 }
84 lIter->next(item);87 theContinueProducer.produce(lCanQuit);
85 std::cout << item.getStringValue() << std::endl;88
86 theContinueProducer.produce(doContinue);89 // go and solve the event with this id
87 theIdQueue.produce(lId);90 theIdQueue.produce(lId);
88 } catch (ZorbaException& e) {91 } catch (ZorbaException& e) {
89 std::cerr << "FATAL: could not execute query: " << std::endl;92 std::cerr << "FATAL: could not execute query: " << std::endl;
90 std::cerr << e << std::endl;93 std::cerr << e << std::endl;
91 std::cerr << "This is a bug, please report to zorba-users@lists.sourceforge.net" << std::endl;94 std::cerr << "This is a bug, please report to zorba-users@lists.sourceforge.net" << std::endl;
92 theContinueProducer.produce(false);95 //theContinueProducer.produce(false);
93 }96 }
94 }97}
95 98
96 void EventHandler::error(unsigned int errcode, const std::string &msg)99void
97 {100EventHandler::error(unsigned int errcode, const std::string &msg)
98 std::cerr << "Error " << errcode << ": " << msg << std::endl;101{
99 }102 std::cerr << "Error " << errcode << ": " << msg << std::endl;
100}}103}
104
105} // namespace zorba
106} // namespace debugger
101107
=== modified file 'bin/debugger/event_handler.h'
--- bin/debug_client/event_handler.h 2011-07-01 01:53:24 +0000
+++ bin/debugger/event_handler.h 2011-12-20 18:15:30 +0000
@@ -14,33 +14,46 @@
14 * limitations under the License.14 * limitations under the License.
15 */15 */
16#pragma once16#pragma once
17#ifndef ZORBA_DEBUGGER_EVENT_HANDLER_H
18#define ZORBA_DEBUGGER_EVENT_HANDLER_H
19
17#include <string>20#include <string>
18#include <iostream>21#include <iostream>
22
19#include <zorba/debugger_event_handler.h>23#include <zorba/debugger_event_handler.h>
20#include <zorba/static_context.h>24#include <zorba/static_context.h>
25
21#include "lock_free_queue.h"26#include "lock_free_queue.h"
2227
23namespace zorba {28
24 class Zorba;29namespace zorba { namespace debugger {
25}30
2631class EventHandler : public zorba::DebuggerEventHandler
27namespace zorba { namespace debugclient {32{
28
29 class EventHandler : public zorba::DebuggerEventHandler
30 {
31 public:33 public:
32 EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContQueue);34 EventHandler(
35 LockFreeProducer<std::size_t>& aQueue,
36 LockFreeProducer<bool>& aContQueue);
37
33 ~EventHandler();38 ~EventHandler();
39
34 public:40 public:
35 virtual void parseMessage(const std::string& aMessage);41 virtual void parseMessage(const std::string& aMessage);
42
36 virtual void error(unsigned int errcode, const std::string& msg);43 virtual void error(unsigned int errcode, const std::string& msg);
44
45 virtual void init();
46
37 private:47 private:
38 static std::istream* getCurrentDirectory();
39 LockFreeProducer<std::size_t>& theIdQueue;48 LockFreeProducer<std::size_t>& theIdQueue;
40 LockFreeProducer<bool>& theContinueProducer;49 LockFreeProducer<bool>& theContinueProducer;
41 void* theStore;50 void* theStore;
42 Zorba* theZorbaInstance;51 Zorba* theZorbaInstance;
43 StaticContext_t theStaticContext;52 StaticContext_t theStaticContext;
44 };53
54};
45 55
46}} // end of namespace zorba::debugclient56} // namespace zorba
57} // namespace debugger
58
59#endif // ZORBA_DEBUGGER_EVENT_HANDLER_H
4760
=== modified file 'bin/debugger/lock_free_queue.h'
--- bin/debug_client/lock_free_queue.h 2011-07-01 01:53:24 +0000
+++ bin/debugger/lock_free_queue.h 2011-12-20 18:15:30 +0000
@@ -14,10 +14,14 @@
14 * limitations under the License.14 * limitations under the License.
15 */15 */
16#pragma once16#pragma once
17#ifndef ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H
18#define ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H
19
17#include <iostream>20#include <iostream>
18#include <list>21#include <list>
1922
20namespace zorba { namespace debugclient {23
24namespace zorba { namespace debugger {
2125
22template<typename T>26template<typename T>
23class LockFreeProducer27class LockFreeProducer
@@ -80,4 +84,8 @@
80 }84 }
81 return false;85 return false;
82}86}
83}} // namespace zorba::debugclient87
88} // namespace zorba
89} // namespace debugger
90
91#endif // ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H
8492
=== modified file 'bin/debugger/main.cpp'
--- bin/debug_client/main.cpp 2011-07-01 01:53:24 +0000
+++ bin/debugger/main.cpp 2011-12-20 18:15:30 +0000
@@ -13,12 +13,244 @@
13 * See the License for the specific language governing permissions and13 * See the License for the specific language governing permissions and
14 * limitations under the License.14 * limitations under the License.
15 */15 */
16
17#ifdef WIN32
18# include <windows.h>
19# include <string.h>
20# include <strsafe.h>
21#endif
22
23#include <vector>
24
16#include <zorba/config.h>25#include <zorba/config.h>
17#include "debug_command.h"26
27#include "command_prompt.h"
18#include "command_line_handler.h"28#include "command_line_handler.h"
1929
20using namespace zorba;30using namespace zorba;
21using namespace zorba::debugclient;31using namespace zorba::debugger;
32
33int
34startZorba(std::string& aExec, std::vector<std::string>& aArgs)
35{
36#ifdef WIN32
37 // **************************
38 // start a process on Windows
39
40 DWORD iReturnVal = 0;
41 DWORD dwExitCode = 0;
42
43 std::wstring lExec;
44 std::wstring lArgs;
45
46 lExec.assign(aExec.begin(), aExec.end());
47
48 // the executable must be the first in the list of arguments
49 lArgs.append(L"\"");
50 lArgs.append(lExec);
51 lArgs.append(L"\"");
52
53 for (std::vector<std::string>::size_type j = 0; j < aArgs.size(); j++) {
54 std::string lArg(aArgs.at(j));
55 std::wstring lArgW;
56 lArgW.assign(lArg.begin(), lArg.end());
57 lArgs.append(L" ");
58 lArgs.append(lArgW);
59 }
60
61 // CreateProcessW can modify Parameters thus we allocate needed memory
62 wchar_t * pwszParam = new wchar_t[lArgs.size() + 1];
63 if (pwszParam == 0) {
64 return 1;
65 }
66 const wchar_t* pchrTemp = lArgs.c_str();
67 wcscpy_s(pwszParam, lArgs.size() + 1, pchrTemp);
68
69 // CreateProcess API initialization
70 STARTUPINFOW siStartupInfo;
71 PROCESS_INFORMATION piProcessInfo;
72 memset(&siStartupInfo, 0, sizeof(siStartupInfo));
73 memset(&piProcessInfo, 0, sizeof(piProcessInfo));
74 siStartupInfo.cb = sizeof(siStartupInfo);
75
76 BOOL lResult = CreateProcessW(
77 const_cast<LPCWSTR>(lExec.c_str()),
78 pwszParam, 0, 0, false,
79 CREATE_DEFAULT_ERROR_MODE, 0, 0,
80 &siStartupInfo, &piProcessInfo);
81
82 if (lResult) {
83 // Watch the process
84 dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, 0);
85 }
86 else {
87 // CreateProcess failed
88 iReturnVal = GetLastError();
89 LPVOID lpMsgBuf;
90 LPVOID lpDisplayBuf;
91
92 FormatMessage(
93 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
94 NULL,
95 iReturnVal,
96 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
97 (LPTSTR) &lpMsgBuf,
98 0, NULL);
99
100 // Display the error message and exit the process
101
102 lpDisplayBuf = (LPVOID)LocalAlloc(
103 LMEM_ZEROINIT,
104 (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
105
106 StringCchPrintf(
107 (LPTSTR)lpDisplayBuf,
108 LocalSize(lpDisplayBuf) / sizeof(TCHAR),
109 TEXT("Error (%d) when starting zorba: %s"),
110 iReturnVal,
111 lpMsgBuf);
112
113 std::wstring lErrorW((wchar_t*)lpDisplayBuf);
114 std::string lError;
115 lError.assign(lErrorW.begin(), lErrorW.end());
116 std::cout << lError << std::endl;
117
118 LocalFree(lpMsgBuf);
119 LocalFree(lpDisplayBuf);
120 }
121
122 // Free memory
123 delete[]pwszParam;
124 pwszParam = 0;
125
126 // Release handles
127 CloseHandle(piProcessInfo.hProcess);
128 CloseHandle(piProcessInfo.hThread);
129
130 return iReturnVal;
131
132#else
133 // ************************
134 // start a process on Linux
135
136 pid_t pID = fork();
137 if (pID == 0) {
138 // Code only executed by child process
139 std::stringstream lCommand;
140 lCommand << aExec;
141 for (std::vector<std::string>::size_type j = 0; j < aArgs.size(); j++) {
142 lCommand << " " << aArgs.at(j);
143 }
144
145 int lRes = system(lCommand.str().c_str());
146 exit(lRes);
147 }
148 else {
149 // Code only executed by parent process
150 if (pID < 0) {
151 std::cerr << "Failed to fork Zorba" << std::endl;
152 return pID;
153 } else {
154 return 0;
155 }
156 }
157#endif
158}
159
160void printUsage(std::string& aProgram)
161{
162 std::cerr << "Usage:" << std::endl
163 << " " << aProgram << " <zorba_arguments>" << std::endl
164 << " this will start a debugger command line and a zorba process with the given arguments" << std::endl;
165}
166
167bool
168processArguments(
169 int argc,
170 char* argv[],
171 std::string& aProgram,
172 bool& aStandalone,
173 std::string& aZorba,
174 unsigned int& aPort,
175 std::vector<std::string>& aZorbaArgs)
176{
177 aPort = 28028;
178
179 // find the path to Zorba and this executable name
180 aProgram = argv[0];
181
182#ifdef WIN32
183 char lSep = '\\';
184#else
185 char lSep = '/';
186#endif
187 std::string::size_type lPos = aProgram.find_last_of(lSep);
188
189 std::stringstream lZs;
190
191 if (lPos == aProgram.npos) {
192 lZs << "." << lSep;
193 } else {
194 lZs << aProgram.substr(0, lPos + 1);
195 aProgram = aProgram.substr(lPos + 1);
196 }
197 lZs << "zorba";
198#ifdef WIN32
199 lZs << ".exe";
200#endif
201 aZorba = lZs.str();
202
203
204 bool lHasFileArg = false;
205 bool lHasQueryArg = false;
206 bool lHasQueryVal = false;
207
208 // find if the user asked for help or specified a specific port
209 for (int i = 1; i < argc; i++) {
210 std::string lArg = argv[i];
211 if (lArg == "-h" || lArg == "--help") {
212 return false;
213 }
214 else if (lArg == "-p" || lArg == "--debug-port") {
215 // if there is one more argument
216 if (i < argc - 1) {
217 // get the port value
218 int lPort;
219 std::stringstream lStream(argv[i + 1]);
220 lStream >> lPort;
221 if (!lStream.fail()) {
222 aPort = lPort;
223 }
224 }
225 }
226 else if (lArg == "-f") {
227 lHasFileArg = true;
228 }
229 else if (lArg == "-q") {
230 lHasQueryArg = true;
231 if (++i < argc) {
232 lHasQueryVal = true;
233 }
234 }
235 }
236
237 if (!lHasFileArg || !lHasQueryArg || !lHasQueryVal) {
238 std::cout << "Not enough arguments to start Zorba." << std::endl;
239 std::cout << "Running the standalone XQuery debugger client on port: " << aPort << std::endl;
240 return true;
241 }
242
243 // zorba will need the -d flag
244 aZorbaArgs.push_back("-d");
245
246 // gather all arguments (excepting the program name)
247 for (int i = 1; i < argc; i++) {
248 aZorbaArgs.push_back(argv[i]);
249 }
250
251 aStandalone = false;
252 return true;
253}
22254
23#ifndef _WIN32_WCE255#ifndef _WIN32_WCE
24int256int
@@ -28,24 +260,68 @@
28_tmain(int argc, _TCHAR* argv[])260_tmain(int argc, _TCHAR* argv[])
29#endif261#endif
30{262{
31 int port = 28028;263 // **************************************************************************
32 if (argv[1]) {264 // processing arguments
33 std::stringstream stream(argv[1]);265
34 stream >> port;266 std::string lProgram, lZorbaExec;
35 if (stream.fail() || argv[2]) {267 unsigned int lPort = 28028;
36 std::cerr << "Unknown argument. USAGE: " << argv[0] << " [PORT]" << std::endl;268 std::vector<std::string> lZorbaArgs;
37 return 2;269
270 bool lStandalone = true;
271 if (!processArguments(argc, argv, lProgram, lStandalone, lZorbaExec, lPort, lZorbaArgs)) {
272 printUsage(lProgram);
273 return 1;
274 }
275
276#ifndef NDEBUG
277 // **************************************************************************
278 // debug reporting
279
280 if (!lStandalone) {
281 std::cout << "Communication port: " << lPort << std::endl;
282 std::cout << "Zorba executable: " << lZorbaExec << std::endl;
283 std::cout << "Zorba arguments: ";
284 for (std::vector<std::string>::size_type j = 0; j < lZorbaArgs.size(); j++) {
285 std::cout << lZorbaArgs.at(j) << " ";
38 }286 }
287 std::cout << std::endl;
39 }288 }
289#endif
290
40 try {291 try {
292 // **************************************************************************
293 // start a zorba
294
295 if (!lStandalone) {
296 int lResult = startZorba(lZorbaExec, lZorbaArgs);
297 if (lResult) {
298 return lResult;
299 }
300 } else {
301 std::cout << "Waiting for an incomming Zorba connection..." << std::endl;
302 }
303
304 // **************************************************************************
305 // start the debugger command line
306
41 LockFreeQueue<std::size_t> lQueue;307 LockFreeQueue<std::size_t> lQueue;
42 LockFreeQueue<bool> lContEvent;308 LockFreeQueue<bool> lContEvent;
43 EventHandler lHandler(lQueue, lContEvent);309 EventHandler lEventHandler(lQueue, lContEvent);
44 CommandLine cli;310 lEventHandler.init();
45 CommandLineHandler handler(port, lQueue, lContEvent, lHandler, cli);311
46 handler.execute();312 CommandPrompt lCommandPrompt;
313 CommandLineHandler lCommandLineHandler(lPort, lQueue, lContEvent, lEventHandler, lCommandPrompt);
314
315 lCommandLineHandler.execute();
316
317#ifndef WIN32
318 wait();
319#endif
320
47 } catch (...) {321 } catch (...) {
48 return 4;322 return -1;
49 }323 }
324
50 return 0;325 return 0;
51}326}
327
52328
=== modified file 'bin/debugger/tuple.h'
--- bin/debug_client/tuple.h 2011-07-04 08:05:46 +0000
+++ bin/debugger/tuple.h 2011-12-20 18:15:30 +0000
@@ -14,9 +14,15 @@
14 * limitations under the License.14 * limitations under the License.
15 */15 */
16#pragma once16#pragma once
17#ifndef ZORBA_DEBUGGER_TUPLE_H
18#define ZORBA_DEBUGGER_TUPLE_H
19
17#include <zorba/config.h>20#include <zorba/config.h>
21
18#if ZORBA_TR1_IN_TR1_SUBDIRECTORY22#if ZORBA_TR1_IN_TR1_SUBDIRECTORY
19# include <tr1/tuple>23# include <tr1/tuple>
20#else24#else
21# include <tuple>25# include <tuple>
22#endif26#endif
27
28#endif // ZORBA_DEBUGGER_TUPLE_H
2329
=== modified file 'bin/zorbacmd.cpp'
--- bin/zorbacmd.cpp 2011-11-08 03:11:02 +0000
+++ bin/zorbacmd.cpp 2011-12-20 18:15:30 +0000
@@ -925,17 +925,15 @@
925 lHost = "127.0.0.1";925 lHost = "127.0.0.1";
926 }926 }
927927
928 if (lProperties.debug()) {928 Zorba_SerializerOptions lSerOptions =
929 Zorba_SerializerOptions lSerOptions =929 Zorba_SerializerOptions::SerializerOptionsFromStringParams(
930 Zorba_SerializerOptions::SerializerOptionsFromStringParams(930 lProperties.getSerializerParameters());
931 lProperties.getSerializerParameters());931 createSerializerOptions(lSerOptions, lProperties);
932 createSerializerOptions(lSerOptions, lProperties);
933932
934 if (!lProperties.hasNoLogo() && !lProperties.debug()) {933 if (!lProperties.hasNoLogo()) {
935 std::cout << "Zorba XQuery Debugger Server\n" << copyright_str << std::endl;934 std::cout << "Zorba XQuery Debugger Server\n" << copyright_str << std::endl;
936 }
937 lQuery->debug(*lOutputStream, lSerOptions, lHost, lProperties.getDebugPort());
938 }935 }
936 lQuery->debug(*lOutputStream, lSerOptions, lHost, lProperties.getDebugPort());
939 }937 }
940 catch (zorba::XQueryException const& qe)938 catch (zorba::XQueryException const& qe)
941 {939 {
942940
=== added file 'cmake_modules/FindLibedit.cmake'
--- cmake_modules/FindLibedit.cmake 1970-01-01 00:00:00 +0000
+++ cmake_modules/FindLibedit.cmake 2011-12-20 18:15:30 +0000
@@ -0,0 +1,46 @@
1# Copyright 2011 The FLWOR Foundation.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15# - Try to find the libedit library
16#
17# Once done this will define
18#
19# LIBEDIT_FOUND - True if libedit library is found
20# LIBEDIT_INCLUDE_DIRS - Directory to include to get libedit headers
21# LIBEDIT_LIBRARIES - Libraries to link against for the libedit library
22#
23
24FIND_PATH (
25 LIBEDIT_INCLUDE
26 editline/readline.h
27 PATHS ${LIBEDIT_INCLUDE_DIR} /usr/include /usr/local/include
28)
29MESSAGE(STATUS ${LIBEDIT_INCLUDE})
30
31FIND_LIBRARY (
32 LIBEDIT_LIBRARY
33 NAMES edit
34 PATHS ${LIBEDIT_LIBRARY_DIR} /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64
35)
36MESSAGE(STATUS ${LIBEDIT_LIBRARY})
37
38SET (LIBEDIT_INCLUDE_DIRS ${LIBEDIT_INCLUDE})
39SET (LIBEDIT_LIBRARIES ${LIBEDIT_LIBRARY})
40
41FIND_PACKAGE_HANDLE_STANDARD_ARGS (
42 Libedit
43 DEFAULT_MSG
44 LIBEDIT_INCLUDE LIBEDIT_LIBRARY
45)
46
047
=== modified file 'include/zorba/config.h.cmake'
--- include/zorba/config.h.cmake 2011-10-19 16:19:45 +0000
+++ include/zorba/config.h.cmake 2011-12-20 18:15:30 +0000
@@ -39,19 +39,19 @@
39#endif /* WIN32 */39#endif /* WIN32 */
4040
41// Platform headers41// Platform headers
42#cmakedefine ZORBA_HAVE_COLL_H 42#cmakedefine ZORBA_HAVE_COLL_H
43#cmakedefine ZORBA_HAVE_EXECINFO_H43#cmakedefine ZORBA_HAVE_EXECINFO_H
44#cmakedefine ZORBA_HAVE_FLEXLEXER_H44#cmakedefine ZORBA_HAVE_FLEXLEXER_H
45#cmakedefine ZORBA_HAVE_ICONV_H45#cmakedefine ZORBA_HAVE_ICONV_H
46#cmakedefine ZORBA_HAVE_INTTYPES_H 46#cmakedefine ZORBA_HAVE_INTTYPES_H
47#cmakedefine ZORBA_HAVE_LIMITS_H 47#cmakedefine ZORBA_HAVE_LIMITS_H
48#cmakedefine ZORBA_HAVE_PTHREAD_H 48#cmakedefine ZORBA_HAVE_PTHREAD_H
49#cmakedefine ZORBA_HAVE_STDINT_H 49#cmakedefine ZORBA_HAVE_STDINT_H
50#cmakedefine ZORBA_HAVE_STDLIB_H 50#cmakedefine ZORBA_HAVE_STDLIB_H
51#cmakedefine ZORBA_HAVE_SYS_MOUNT_H51#cmakedefine ZORBA_HAVE_SYS_MOUNT_H
52#cmakedefine ZORBA_HAVE_SYS_TYPES_H52#cmakedefine ZORBA_HAVE_SYS_TYPES_H
53#cmakedefine ZORBA_HAVE_USTRING_H 53#cmakedefine ZORBA_HAVE_USTRING_H
54#cmakedefine ZORBA_HAVE_UTYPES_H 54#cmakedefine ZORBA_HAVE_UTYPES_H
5555
56// Platform functions56// Platform functions
57#cmakedefine ZORBA_HAVE_CLOCKGETTIME_FUNCTION57#cmakedefine ZORBA_HAVE_CLOCKGETTIME_FUNCTION
5858
=== modified file 'include/zorba/debugger_client.h'
--- include/zorba/debugger_client.h 2011-07-24 22:28:31 +0000
+++ include/zorba/debugger_client.h 2011-12-20 18:15:30 +0000
@@ -162,6 +162,13 @@
162 * @return The id of the request.162 * @return The id of the request.
163 */163 */
164 virtual std::size_t status() = 0;164 virtual std::size_t status() = 0;
165
166 /**
167 * @brief Get the variables in all the contexts in the topmost stack frame.
168 *
169 * @return The id of the request.
170 */
171 virtual std::size_t variables() = 0;
165 172
166 /**173 /**
167 * @brief Query the debug engine for supported features.174 * @brief Query the debug engine for supported features.
@@ -521,6 +528,7 @@
521 */528 */
522 virtual void quit() = 0;529 virtual void quit() = 0;
523 };530 };
531
524}//end of namespace532}//end of namespace
533
525#endif534#endif
526/* vim:set et sw=2 ts=2: */
527535
=== modified file 'modules/com/zorba-xquery/www/modules/CMakeLists.txt'
--- modules/com/zorba-xquery/www/modules/CMakeLists.txt 2011-10-14 07:35:51 +0000
+++ modules/com/zorba-xquery/www/modules/CMakeLists.txt 2011-12-20 18:15:30 +0000
@@ -100,6 +100,13 @@
100DECLARE_ZORBA_MODULE(FILE store/static/integrity_constraints/dml.xq VERSION 2.0100DECLARE_ZORBA_MODULE(FILE store/static/integrity_constraints/dml.xq VERSION 2.0
101 URI "http://www.zorba-xquery.com/modules/store/static/integrity_constraints/dml")101 URI "http://www.zorba-xquery.com/modules/store/static/integrity_constraints/dml")
102102
103# debugger client DBGP message handler module
104IF (ZORBA_WITH_DEBUGGER)
105 DECLARE_ZORBA_MODULE (FILE debugger/dbgp-message-handler.xq VERSION 1.0
106 URI "http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler")
107ENDIF (ZORBA_WITH_DEBUGGER)
108
109
103# error and warning modules110# error and warning modules
104DECLARE_ZORBA_MODULE (FILE pregenerated/errors.xq111DECLARE_ZORBA_MODULE (FILE pregenerated/errors.xq
105 URI "http://www.zorba-xquery.com/errors"112 URI "http://www.zorba-xquery.com/errors"
106113
=== added directory 'modules/com/zorba-xquery/www/modules/debugger'
=== added file 'modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq'
--- modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq 1970-01-01 00:00:00 +0000
+++ modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq 2011-12-20 18:15:30 +0000
@@ -0,0 +1,277 @@
1xquery version "3.0";
2
3(:
4 : Copyright 2006-2009 The FLWOR Foundation.
5 :
6 : Licensed under the Apache License, Version 2.0 (the "License");
7 : you may not use this file except in compliance with the License.
8 : You may obtain a copy of the License at
9 :
10 : http://www.apache.org/licenses/LICENSE-2.0
11 :
12 : Unless required by applicable law or agreed to in writing, software
13 : distributed under the License is distributed on an "AS IS" BASIS,
14 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : See the License for the specific language governing permissions and
16 : limitations under the License.
17:)
18module namespace dmh = "http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler";
19
20import module namespace base64 = "http://www.zorba-xquery.com/modules/converters/base64";
21
22declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
23declare option ver:module-version "1.0";
24
25
26declare variable $dmh:endl as xs:string := "
27";
28
29(:~
30 : Set this variale to true if you want to have mode debug information when
31 : an error occurs.
32 :)
33declare variable $dmh:debug as xs:boolean := fn:false();
34
35
36declare %private function dmh:status($resp as element(response))
37{
38 switch ($resp/@status)
39 case "starting"
40 case "stopping"
41 return "idle"
42 case "break"
43 return
44 let $status := $resp/@status
45 let $whyInfo :=
46 if ($resp/@reason ne "ok") then
47 fn:concat(" (", $resp/@reason, ")")
48 else
49 ""
50 let $whereInfo :=
51 if ($resp/text()[1] ne "") then
52 fn:concat(" in ", $resp/text()[1])
53 else
54 ""
55 return
56 fn:concat($status, $whyInfo, $whereInfo)
57 default
58 return $resp/@status
59};
60
61declare %private function dmh:source($resp as element(response))
62{
63 $resp/text()
64};
65
66declare %private function dmh:breakpoint-set($resp as element(response))
67{
68 fn:concat("set breakpoint with id ", data($resp/@id), " and state ", data($resp/@state))
69};
70
71declare %private function dmh:breakpoint-get($resp as element(response))
72{
73 let $b := $resp/breakpoint
74 return
75 fn:concat(
76 "Breakpoint ", $b/@id, $dmh:endl,
77 " type: ", $b/@type, $dmh:endl,
78 " file: ", $b/@filename, $dmh:endl,
79 " line: ", $b/@lineno, $dmh:endl,
80 " state: ", $b/@state
81 )
82};
83
84declare %private function dmh:breakpoint-list($resp as element(response))
85{
86 fn:string-join(
87 let $bs := $resp/breakpoint
88 return
89 if (fn:exists($bs)) then
90 fn:concat(
91 "--------------------------------------", $dmh:endl,
92 "| ID | State | Line | File", $dmh:endl,
93 "|--------|-----------|--------|-------", $dmh:endl,
94 fn:string-join(
95 for $b in $bs
96 return
97 fn:concat(
98 "| ", dmh:lpottl($b/@id, 6, " "), " ",
99 "| ", if ($b/@state eq "enabled") then "enabled " else "disabled ", " ",
100 "| ", dmh:lpottl($b/@lineno, 6, " "), " ",
101 "| ", $b/@filename, $dmh:endl),
102 ""
103 ),
104 "--------------------------------------", $dmh:endl
105 )
106 else
107 "No breakpoints set"
108 )
109};
110
111(:~
112 : left-pad-or-trim-to-length
113 :)
114declare %private function dmh:lpottl($value as xs:string, $length as xs:integer, $padChar as xs:string)
115 as xs:string
116{
117 let $padChar := fn:substring($padChar, 1, 1)
118 let $len := fn:string-length($value)
119 return
120 if ($len < $length) then
121 let $pad :=
122 fn:string-join(
123 for $i in 1 to $length - $len
124 return $padChar,
125 ""
126 )
127 return
128 fn:concat($pad, $value)
129 else
130 fn:substring($value, $len - $length + 1)
131};
132
133declare %private function dmh:breakpoint-remove($resp as element(response))
134{
135 "Breakpoint removed"
136};
137
138declare %private function dmh:stack-depth($resp as element(response))
139{
140 fn:concat("depth: ", $resp/@depth)
141};
142
143declare %private function dmh:stack-get($resp as element(response))
144{
145 fn:string-join(
146 for $s in $resp/stack
147 return
148 fn:concat("#", $s/@level, " in ", $s/@where, " at ", $s/@filename, ":", $s/@lineno),
149 $dmh:endl
150 )
151};
152
153
154declare %private function dmh:context-names($resp as element(response))
155{
156 fn:string-join(
157 for $c in $resp/context
158 return
159 fn:concat("context ", $c/@id, ": ", $c/@name),
160 $dmh:endl
161 )
162};
163
164declare %private function dmh:context-get($resp as element(response))
165{
166 fn:string-join(
167 for $p in $resp/property
168 return
169 fn:concat($p/@fullname, " ", $p/@type,
170 if ($p/text() ne "") then
171 fn:concat(": ", base64:decode($p/text()))
172 else
173 ""
174 ),
175 $dmh:endl
176 )
177};
178
179declare %private function dmh:eval($resp as element(response))
180{
181 if ($resp/@success eq "1") then
182 dmh:context-get($resp)
183 else
184 dmh:report-error("An unknown error occured while evaluating expression.")
185};
186
187declare %private function dmh:report-error(
188 $message as xs:string)
189{
190 dmh:report-error($message, ())
191};
192
193declare %private function dmh:report-error(
194 $message as xs:string,
195 $debugMessage as xs:string*)
196{
197 fn:string-join(
198 (
199 (: the error message :)
200 fn:concat("Error: ", $message),
201
202 (: the debug info :)
203 if ($dmh:debug and fn:string-length($debugMessage) gt 0) then
204 $debugMessage
205 else
206 ()
207 ),
208 $dmh:endl
209 )
210};
211
212declare %private function dmh:process-response($resp as element(response))
213{
214 switch ($resp/@command)
215 case "eval" return dmh:eval($resp)
216 case "context_get" return dmh:context-get($resp)
217 case "context_names" return dmh:context-names($resp)
218 case "stack_get" return dmh:stack-get($resp)
219 case "stack_depth" return dmh:stack-depth($resp)
220 case "breakpoint_remove" return dmh:breakpoint-remove($resp)
221 case "breakpoint_list" return dmh:breakpoint-list($resp)
222 case "breakpoint_get" return dmh:breakpoint-get($resp)
223 case "breakpoint_set" return dmh:breakpoint-set($resp)
224 case "source" return dmh:source($resp)
225
226 (: continuation command only need to display/process the status :)
227 case "run"
228 case "step_into"
229 case "step_out"
230 case "step_over"
231 case "stop"
232 case "status"
233 return dmh:status($resp)
234
235 default
236 return dmh:report-error(fn:concat("Command not implemented: ", $resp/@command))
237};
238
239declare function dmh:process-init($init as element(init))
240{
241 fn:string-join(
242 ("Established connection with", $init/@language, "client", $init/@appid),
243 " "
244 )
245};
246
247declare function dmh:process($message as element())
248{
249 let $nodeName := fn:local-name($message)
250 let $id := fn:data($message/@transaction_id)
251 return
252 if ($nodeName eq "response") then
253 (: no transaction_id :)
254 if (fn:count($id) eq 0 or $id eq "") then
255 (0, dmh:report-error("Invalid response", "Missing or empty response transaction ID."))
256 (: wrong transaction_id :)
257 else if (xs:string(fn:number($id)) eq "NaN") then
258 (0, dmh:report-error("Invalid response", "Invalid value for response transaction ID."))
259 (: no or empty command :)
260 else if (fn:count($message/@command) eq 0 or $message/@command eq "") then
261 ($id, dmh:report-error("Invalid response", "Missing or empty response command attribute."))
262 (: error response :)
263 else if (fn:exists($message/error)) then
264 ($id, dmh:report-error(fn:data($message/error/message), fn:concat("Error code: ", fn:data($message/error/@code))))
265 else
266 ($id, dmh:process-response($message))
267 else if ($nodeName eq "init") then
268 (0, dmh:process-init($message))
269 else
270 (
271 if (fn:count($id) eq 0 or $id eq "" or xs:string(fn:number($id)) eq "NaN") then
272 0
273 else
274 $id,
275 dmh:report-error(fn:concat("Unknown message node: ", $nodeName))
276 )
277};
0278
=== modified file 'src/compiler/expression/expr.cpp'
--- src/compiler/expression/expr.cpp 2011-12-20 09:04:58 +0000
+++ src/compiler/expression/expr.cpp 2011-12-20 18:15:30 +0000
@@ -1469,7 +1469,6 @@
1469 compute_scripting_kind();1469 compute_scripting_kind();
1470}1470}
14711471
1472
1473void debugger_expr::serialize(::zorba::serialization::Archiver& ar)1472void debugger_expr::serialize(::zorba::serialization::Archiver& ar)
1474{1473{
1475 serialize_baseclass(ar, (expr*)this);1474 serialize_baseclass(ar, (expr*)this);
14761475
=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp 2011-12-20 11:50:23 +0000
+++ src/compiler/translator/translator.cpp 2011-12-20 18:15:30 +0000
@@ -1671,7 +1671,7 @@
1671void wrap_in_debugger_expr(1671void wrap_in_debugger_expr(
1672 expr_t& aExpr,1672 expr_t& aExpr,
1673 const QueryLoc& aLoc,1673 const QueryLoc& aLoc,
1674 bool aAddBreakable = true,1674 bool aIsMainModuleBreakable = false,
1675 bool aIsVarDeclaration = false)1675 bool aIsVarDeclaration = false)
1676{1676{
1677#ifdef ZORBA_WITH_DEBUGGER1677#ifdef ZORBA_WITH_DEBUGGER
@@ -1686,9 +1686,7 @@
1686 // add the breakable expression in the debugger commons as a possible1686 // add the breakable expression in the debugger commons as a possible
1687 // breakpoint location1687 // breakpoint location
1688 Breakable lBreakable(aLoc);1688 Breakable lBreakable(aLoc);
1689 if (aAddBreakable) {1689 theCCB->theDebuggerCommons->addBreakable(lBreakable, aIsMainModuleBreakable);
1690 theCCB->theDebuggerCommons->addBreakable(lBreakable);
1691 }
16921690
1693 // retrieve all variables that are in the current scope1691 // retrieve all variables that are in the current scope
1694 typedef std::vector<var_expr_t> VarExprVector;1692 typedef std::vector<var_expr_t> VarExprVector;
@@ -2246,7 +2244,7 @@
2246 // the main module debug iterator has no location otherwise2244 // the main module debug iterator has no location otherwise
2247 // this would take precedence over a child debug iterator2245 // this would take precedence over a child debug iterator
2248 // starting in the same line2246 // starting in the same line
2249 wrap_in_debugger_expr(program, program->get_loc(), false);2247 wrap_in_debugger_expr(program, program->get_loc(), true);
22502248
2251 program = wrap_in_globalvar_assign(program);2249 program = wrap_in_globalvar_assign(program);
22522250
@@ -3725,7 +3723,7 @@
3725 QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(),3723 QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(),
3726 initExpr->get_loc());3724 initExpr->get_loc());
37273725
3728 wrap_in_debugger_expr(initExpr, lExpandedLocation, true, true);3726 wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
3729 }3727 }
3730#endif3728#endif
37313729
@@ -3747,7 +3745,7 @@
3747 QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(),3745 QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(),
3748 initExpr->get_loc());3746 initExpr->get_loc());
37493747
3750 wrap_in_debugger_expr(initExpr, lExpandedLocation, true, true);3748 wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true);
3751 }3749 }
3752#endif3750#endif
37533751
37543752
=== modified file 'src/debugger/debugger_client.cpp'
--- src/debugger/debugger_client.cpp 2011-06-14 17:26:33 +0000
+++ src/debugger/debugger_client.cpp 2011-12-20 18:15:30 +0000
@@ -38,5 +38,3 @@
38}38}
3939
40}//end of namespace40}//end of namespace
41
42/* vim:set et sw=2 ts=2: */
4341
=== modified file 'src/debugger/debugger_clientimpl.cpp'
--- src/debugger/debugger_clientimpl.cpp 2011-07-06 20:43:46 +0000
+++ src/debugger/debugger_clientimpl.cpp 2011-12-20 18:15:30 +0000
@@ -24,462 +24,549 @@
2424
25namespace zorba {25namespace zorba {
26 26
27 DebuggerClient::~DebuggerClient()27DebuggerClient*
28 {}28DebuggerClient::createDebuggerClient(
29 29 DebuggerEventHandler* aHandler,
30 DebuggerClient* DebuggerClient::createDebuggerClient(DebuggerEventHandler* aHandler,30 unsigned short aPort,
31 unsigned short aPort,31 const std::string& aHost)
32 const std::string& aHost)32{
33 {33 return new DebuggerClientImpl(aHost, aPort, aHandler);
34 return new DebuggerClientImpl(aHost, aPort, aHandler);34}
35 }35
36 36// ****************************************************************************
37 DebuggerListener::DebuggerListener(DebuggerClientImpl* aClient)37
38DebuggerListener::DebuggerListener(DebuggerClientImpl* aClient)
38 : theClient(aClient), theStopLooping(false)39 : theClient(aClient), theStopLooping(false)
39 {40{
40 }41}
41 42
42 void DebuggerListener::run()43void
43 {44DebuggerListener::run()
44 while (!theStopLooping) {45{
45 std::string str;46 while (!theStopLooping) {
46 std::getline(*(theClient->theStream), str, '\0');47 std::string str;
47#ifndef NDEBUG48 std::getline(*(theClient->theInStream), str, '\0');
48 std::stringstream lStr(str);49
49 std::size_t length;50#ifndef NDEBUG
50 lStr >> length;51 std::stringstream lStr(str);
51#endif52 std::size_t length;
52 // we are not interested in the length, but only in the init53 lStr >> length;
53 // message54#endif
54 std::getline(*(theClient->theStream), str, '\0');55
55#ifndef NDEBUG56 // we are not interested in the length, but only in the init message
56 assert(str.size() == length);57 std::getline(*(theClient->theInStream), str, '\0');
57#endif58
58 theClient->theHandler->parseMessage(str);59#ifndef NDEBUG
59 this->sleep_(1000);60 assert(str.size() == length);
60 }61#endif
61 }62
62 63 theClient->theHandler->parseMessage(str);
63 void DebuggerListener::finish()64
64 {65 // TODO: this was the initial implementation. This will have to change
65 }66 this->sleep_(1000);
66 67 }
67 void DebuggerListener::stopLooping()68}
68 {69
69 theStopLooping = true;70void
70 }71DebuggerListener::finish()
71 72{
72 DebuggerClientImpl::DebuggerClientImpl(const std::string& aHost,73}
73 unsigned short aPort,74
74 DebuggerEventHandler* aHandler)75void
75 : theServerSocket(aHost, aPort), theSocket(0), theStreamBuffer(0), theStream(0),76DebuggerListener::stopLooping()
76 theHandler(aHandler), theListener(this), theLastId(0)77{
77 {78 theStopLooping = true;
78 }79}
79 80
80 void DebuggerClientImpl::accept() {81// ****************************************************************************
81 theSocket = theServerSocket.accept();82
82 theStreamBuffer = new socket_streambuf(*theSocket);83DebuggerClient::~DebuggerClient()
83 theStream = new std::iostream(theStreamBuffer);84{
84 theListener.start();85}
85 }86
86 87DebuggerClientImpl::DebuggerClientImpl(
87 std::size_t DebuggerClientImpl::status()88 const std::string& aHost,
88 {89 unsigned short aPort,
89 std::size_t id = ++theLastId;90 DebuggerEventHandler* aHandler)
90 *theStream << "status -i " << id << '\0';91 : theServerSocket(aHost, aPort),
91 theStream->sync();92 theSocket(0),
92 return id;93 theInStreamBuffer(0),
93 }94 theOutStreamBuffer(0),
94 95 theInStream(0),
95 std::size_t DebuggerClientImpl::feature_get(std::string const& aFeatureName)96 theOutStream(0),
96 {97 theHandler(aHandler),
97 std::size_t id = ++theLastId;98 theListener(0),
98 *theStream << "feature-get -i " << id << " -n " << aFeatureName << '\0';99 theLastId(0)
99 theStream->sync();100{
100 return id;101}
101 }102
102 103DebuggerClientImpl::~DebuggerClientImpl()
103 std::size_t DebuggerClientImpl::feature_set(std::string const &aFeatureName,104{
104 std::string const &aValue)105 if (theListener) {
105 {106 if (theListener->status() == DebuggerListener::RUNNING) {
106 std::size_t id = ++theLastId;107 theListener->stopLooping();
107 *theStream << "feature-set -i " << id << " -n " << aFeatureName << " -v "108 theListener->join();
108 << aValue << '\0';109 }
109 theStream->sync();110 delete theListener;
110 return id;111 }
111 }112 if (theSocket) {
112 113 theInStream->sync();
113 std::size_t DebuggerClientImpl::run()114 delete theInStream;
114 {115
115 std::size_t id = ++theLastId;116 theOutStream->flush();
116 *theStream << "run -i " << id << '\0';117 delete theInStream;
117 theStream->sync();118
118 return id;119 delete theOutStreamBuffer;
119 }120 delete theInStreamBuffer;
120 121
121 std::size_t DebuggerClientImpl::step_into()122 theSocket->close();
122 {123 theSocket->cleanUp();
123 std::size_t id = ++theLastId;124 delete theSocket;
124 *theStream << "step_into -i " << id << '\0';125 }
125 theStream->sync();126}
126 return id;127
127 }128void
128 129DebuggerClientImpl::accept()
129 std::size_t DebuggerClientImpl::step_over()130{
130 {131 theListener = new DebuggerListener(this);
131 std::size_t id = ++theLastId;132 theSocket = theServerSocket.accept();
132 *theStream << "step_over -i " << id << '\0';133 theInStreamBuffer = new SocketStreambuf(*theSocket);
133 theStream->sync();134 theOutStreamBuffer = new SocketStreambuf(*theSocket);
134 return id;135 theInStream = new std::istream(theInStreamBuffer);
135 }136 theOutStream = new std::ostream(theOutStreamBuffer);
136 137 theListener->start();
137 std::size_t DebuggerClientImpl::step_out()138}
138 {139
139 std::size_t id = ++theLastId;140std::size_t
140 *theStream << "step_out -i " << id << '\0';141DebuggerClientImpl::status()
141 theStream->sync();142{
142 return id;143 std::size_t id = ++theLastId;
143 }144 *theOutStream << "status -i " << id << '\0';
144 145 theOutStream->flush();
145 std::size_t DebuggerClientImpl::stop()146 return id;
146 {147}
147 std::size_t id = ++theLastId;148
148 *theStream << "stop -i " << id << '\0';149std::size_t
149 theStream->sync();150DebuggerClientImpl::variables()
150 return id;151{
151 }152 // we hack the protocol to return all properties if the context ID is -1
152 153 std::size_t id = ++theLastId;
153 std::size_t DebuggerClientImpl::detach()154 *theOutStream << "context_get -c -1 -i " << id << '\0';
154 {155 theOutStream->flush();
155 std::size_t id = ++theLastId;156 return id;
156 *theStream << "detach -i " << id << '\0';157}
157 theStream->sync();158
158 return id;159std::size_t
159 }160DebuggerClientImpl::feature_get(std::string const& aFeatureName)
160 161{
161 std::size_t DebuggerClientImpl::breakpoint_set(BreakpointType aType,162 std::size_t id = ++theLastId;
162 bool aEnabled,163 *theOutStream << "feature_get -i " << id << " -n " << aFeatureName << '\0';
163 const std::string& aFilename,164 theOutStream->flush();
164 int aLinenumber,165 return id;
165 const std::string& aFunctionName,166}
166 const std::string& aExceptionName,167
167 unsigned hit_value,168std::size_t
168 HitCondition aCondition,169DebuggerClientImpl::feature_set(std::string const &aFeatureName,
169 bool aIsTemporary,170 std::string const &aValue)
170 const std::string& aExpression)171{
171 {172 std::size_t id = ++theLastId;
172 std::size_t id = ++theLastId;173 *theOutStream << "feature_set -i " << id << " -n " << aFeatureName << " -v "
173 *theStream << "breakpoint_set -i " << id174 << aValue << '\0';
174 << " -t ";175 theOutStream->flush();
175 switch (aType) {176 return id;
176 case Line:177}
177 *theStream << "line";178
178 break;179std::size_t
179 case Call:180DebuggerClientImpl::run()
180 *theStream << "call";181{
181 break;182 std::size_t id = ++theLastId;
182 case Return:183 *theOutStream << "run -i " << id << '\0';
183 *theStream << "return";184 theOutStream->flush();
184 break;185 return id;
185 case Exception:186}
186 *theStream << "exception";187
187 break;188std::size_t
188 case Conditional:189DebuggerClientImpl::step_into()
189 *theStream << "conditional";190{
190 break;191 std::size_t id = ++theLastId;
191 case Watch:192 *theOutStream << "step_into -i " << id << '\0';
192 *theStream << "watch";193 theOutStream->flush();
193 break;194 return id;
194 }195}
195 if (!aEnabled)196
196 *theStream << " -s disabled";197std::size_t
197 if (aFilename != "") {198DebuggerClientImpl::step_over()
198 *theStream << " -f " << aFilename;199{
199 }200 std::size_t id = ++theLastId;
200 if (aLinenumber != -1)201 *theOutStream << "step_over -i " << id << '\0';
201 *theStream << " -n " << aLinenumber;202 theOutStream->flush();
202 if (aFunctionName != "")203 return id;
203 *theStream << " -m " << aFunctionName;204}
204 if (aExceptionName != "")205
205 *theStream << " -x " << aExceptionName;206std::size_t
206 if (hit_value != 0)207DebuggerClientImpl::step_out()
207 *theStream << " -h " << hit_value;208{
208 switch (aCondition) {209 std::size_t id = ++theLastId;
209 case BiggerEqual:210 *theOutStream << "step_out -i " << id << '\0';
210 break;211 theOutStream->flush();
211 case Equal:212 return id;
212 *theStream << " -o == ";213}
213 break;214
214 case Multiple:215std::size_t
215 *theStream << " -o % ";216DebuggerClientImpl::stop()
216 }217{
217 if (aIsTemporary)218 std::size_t id = ++theLastId;
218 *theStream << " -r 1 ";219 *theOutStream << "stop -i " << id << '\0';
219 if (aExpression != "")220 theOutStream->flush();
220 *theStream << " -- " << aExpression;221 return id;
221 *theStream << '\0';222}
222 theStream->sync();223
223 return id;224std::size_t
224 }225DebuggerClientImpl::detach()
225 226{
226 std::size_t DebuggerClientImpl::breakpoint_get(std::size_t aBreakpointId)227 std::size_t id = ++theLastId;
227 {228 *theOutStream << "detach -i " << id << '\0';
228 std::size_t id = ++theLastId;229 theOutStream->flush();
229 *theStream << "breakpoint_get -i " << id << " -d " << aBreakpointId << '\0';230 return id;
230 theStream->sync();231}
231 return id;232
232 }233std::size_t
233 234DebuggerClientImpl::breakpoint_set(
234 std::size_t DebuggerClientImpl::breakpoint_update(std::size_t aBreakpointId,235 BreakpointType aType,
235 bool aEnabled,236 bool aEnabled,
236 int aLinenumber,237 const std::string& aFilename,
237 unsigned hit_value,238 int aLinenumber,
238 HitCondition aCondition)239 const std::string& aFunctionName,
239 {240 const std::string& aExceptionName,
240 std::size_t id = ++theLastId;241 unsigned hit_value,
241 *theStream << "breakpoint_update -i " << id242 HitCondition aCondition,
242 << " -d " << aBreakpointId;243 bool aIsTemporary,
243 if (aEnabled)244 const std::string& aExpression)
244 *theStream << " -s disabled";245{
245 if (aLinenumber != -1)246 std::size_t id = ++theLastId;
246 *theStream << " -n " << aLinenumber;247 *theOutStream << "breakpoint_set -i " << id
247 if (hit_value != 0)248 << " -t ";
248 *theStream << " -h " << hit_value;249 switch (aType) {
249 switch (aCondition) {250 case Line:
250 case BiggerEqual:251 *theOutStream << "line";
251 break;252 break;
252 case Equal:253 case Call:
253 *theStream << " -o == ";254 *theOutStream << "call";
254 break;255 break;
255 case Multiple:256 case Return:
256 *theStream << " -o % ";257 *theOutStream << "return";
257 }258 break;
258 *theStream << '\0';259 case Exception:
259 theStream->sync();260 *theOutStream << "exception";
260 return id;261 break;
261 }262 case Conditional:
262 263 *theOutStream << "conditional";
263 std::size_t DebuggerClientImpl::breakpoint_remove(std::size_t aBreakpointId)264 break;
264 {265 case Watch:
265 std::size_t id = ++theLastId;266 *theOutStream << "watch";
266 *theStream << "breakpoint_remove -i " << id << " -d " << aBreakpointId << '\0';267 break;
267 theStream->sync();268 }
268 return id;269 if (!aEnabled)
269 }270 *theOutStream << " -s disabled";
270 271 if (aFilename != "") {
271 std::size_t DebuggerClientImpl::breakpoint_list()272 *theOutStream << " -f \"" << aFilename << "\"";
272 {273 }
273 std::size_t id = ++theLastId;274 if (aLinenumber != -1)
274 *theStream << "breakpoint_list -i " << id << '\0';275 *theOutStream << " -n " << aLinenumber;
275 theStream->sync();276 if (aFunctionName != "")
276 return id;277 *theOutStream << " -m " << aFunctionName;
277 }278 if (aExceptionName != "")
278 279 *theOutStream << " -x " << aExceptionName;
279 std::size_t DebuggerClientImpl::stack_depth()280 if (hit_value != 0)
280 {281 *theOutStream << " -h " << hit_value;
281 std::size_t id = ++theLastId;282 switch (aCondition) {
282 *theStream << "stack_depth -i " << id << '\0';283 case BiggerEqual:
283 theStream->sync();284 break;
284 return id;285 case Equal:
285 }286 *theOutStream << " -o == ";
286 287 break;
287 std::size_t DebuggerClientImpl::stack_get(int depth)288 case Multiple:
288 {289 *theOutStream << " -o % ";
289 std::size_t id = ++theLastId;290 }
290 *theStream << "stack_depth";291 if (aIsTemporary)
291 if (depth > 0)292 *theOutStream << " -r 1 ";
292 *theStream << " -d " << depth;293 if (aExpression != "")
293 *theStream << " -i " << id << '\0';294 *theOutStream << " -- " << aExpression;
294 theStream->sync();295 *theOutStream << '\0';
295 return id;296 theOutStream->flush();
296 }297 return id;
297 298}
298 std::size_t DebuggerClientImpl::context_names(int depth)299
299 {300std::size_t
300 std::size_t id = ++theLastId;301DebuggerClientImpl::breakpoint_get(std::size_t aBreakpointId)
301 *theStream << "context_names";302{
302 if (depth > 0)303 std::size_t id = ++theLastId;
303 *theStream << " -d " << depth;304 *theOutStream << "breakpoint_get -i " << id << " -d " << aBreakpointId << '\0';
304 *theStream << " -i " << id << '\0';305 theOutStream->flush();
305 theStream->sync();306 return id;
306 return id;307}
307 }308
308 309std::size_t
309 std::size_t DebuggerClientImpl::context_get(int depth, int contextId)310DebuggerClientImpl::breakpoint_update(
310 {311 std::size_t aBreakpointId,
311 std::size_t id = ++theLastId;312 bool aEnabled,
312 *theStream << "context_get";313 int aLinenumber,
313 if (depth > 0)314 unsigned hit_value,
314 *theStream << " -d " << depth;315 HitCondition aCondition)
315 if (contextId > 0)316{
316 *theStream << " -c " << contextId;317 std::size_t id = ++theLastId;
317 *theStream << " -i " << id << '\0';318 *theOutStream << "breakpoint_update -i " << id
318 theStream->sync();319 << " -d " << aBreakpointId;
319 return id;320 if (aEnabled)
320 }321 *theOutStream << " -s disabled";
321 322 if (aLinenumber != -1)
322 std::size_t DebuggerClientImpl::typemap_get()323 *theOutStream << " -n " << aLinenumber;
323 {324 if (hit_value != 0)
324 std::size_t id = ++theLastId;325 *theOutStream << " -h " << hit_value;
325 *theStream << "typemap_get -i " << id << '\0';326 switch (aCondition) {
326 theStream->sync();327 case BiggerEqual:
327 return id;328 break;
328 }329 case Equal:
329 330 *theOutStream << " -o == ";
330 std::size_t DebuggerClientImpl::property_get(const std::string& aPropertyLongName,331 break;
331 int aStackDepth,332 case Multiple:
332 int aContextId,333 *theOutStream << " -o % ";
333 std::size_t aMaxDataSize,334 }
334 int aDatapage,335 *theOutStream << '\0';
335 const std::string& aPropertyKey)336 theOutStream->flush();
336 {337 return id;
337 std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);338}
338 if (aDatapage >= 0)339
339 *theStream << " -p " << aDatapage;340std::size_t
340 if (aPropertyKey != "")341DebuggerClientImpl::breakpoint_remove(std::size_t aBreakpointId)
341 *theStream << " -k " << aPropertyKey;342{
342 *theStream << '\0';343 std::size_t id = ++theLastId;
343 theStream->sync();344 *theOutStream << "breakpoint_remove -i " << id << " -d " << aBreakpointId << '\0';
344 return id;345 theOutStream->flush();
345 }346 return id;
346 347}
347 std::size_t DebuggerClientImpl::property_set(const std::string& aPropertyLongName,348
348 int aStackDepth,349std::size_t
349 int aContextId,350DebuggerClientImpl::breakpoint_list()
350 std::size_t aMaxDataSize,351{
351 const std::string& aPropertyAddress)352 std::size_t id = ++theLastId;
352 {353 *theOutStream << "breakpoint_list -i " << id << '\0';
353 std::size_t id = property_x("property_set", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);354 theOutStream->flush();
354 if (aPropertyAddress != "")355 return id;
355 *theStream << " -a " << aPropertyAddress;356}
356 *theStream << '\0';357
357 theStream->sync();358std::size_t
358 return id;359DebuggerClientImpl::stack_depth()
359 }360{
360 361 std::size_t id = ++theLastId;
361 std::size_t DebuggerClientImpl::property_value(const std::string& aPropertyLongName,362 *theOutStream << "stack_depth -i " << id << '\0';
362 int aStackDepth,363 theOutStream->flush();
363 int aContextId,364 return id;
364 std::size_t aMaxDataSize,365}
365 int aDatapage,366
366 const std::string& aPropertyKey,367std::size_t
367 const std::string& aPropertyAddress)368DebuggerClientImpl::stack_get(int depth)
368 {369{
369 std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);370 std::size_t id = ++theLastId;
370 if (aDatapage >= 0)371 *theOutStream << "stack_get";
371 *theStream << " -p " << aDatapage;372 if (depth >= 0) {
372 if (aPropertyKey != "")373 *theOutStream << " -d " << depth;
373 *theStream << " -k " << aPropertyKey;374 }
374 if (aPropertyAddress != "")375 *theOutStream << " -i " << id << '\0';
375 *theStream << " -a " << aPropertyAddress;376 theOutStream->flush();
376 *theStream << '\0';377 return id;
377 theStream->sync();378}
378 return id;379
379 }380std::size_t
380 381DebuggerClientImpl::context_names(int depth)
381 std::size_t DebuggerClientImpl::property_x(const std::string& aCommand,382{
382 const std::string& aPropertyLongName,383 std::size_t id = ++theLastId;
383 int aStackDepth,384 *theOutStream << "context_names";
384 int aContextId,385 if (depth >= 0) {
385 std::size_t aMaxDataSize)386 *theOutStream << " -d " << depth;
386 {387 }
387 std::size_t id = ++theLastId;388 *theOutStream << " -i " << id << '\0';
388 *theStream << aCommand << " -i " << id << " -n " << aPropertyLongName;389 theOutStream->flush();
389 if (aStackDepth > 0)390 return id;
390 *theStream << " -d " << aStackDepth;391}
391 if (aContextId > 0)392
392 *theStream << " -c " << aContextId;393std::size_t
393 if (aMaxDataSize > 0)394DebuggerClientImpl::context_get(int depth, int contextId)
394 *theStream << " -m " << aMaxDataSize;395{
395 theStream->sync();396 std::size_t id = ++theLastId;
396 return id;397 *theOutStream << "context_get";
397 }398 if (depth >= 0) {
398 399 *theOutStream << " -d " << depth;
399 std::size_t DebuggerClientImpl::source(std::string const &aFile,400 }
400 unsigned int aBeginLine,401 if (contextId >= 0){
401 unsigned int aEndLine)402 *theOutStream << " -c " << contextId;
402 {403 }
403 std::size_t id = ++theLastId;404 *theOutStream << " -i " << id << '\0';
404 *theStream << "source -i " << id << " -f " << aFile;405 theOutStream->flush();
405 if (aBeginLine)406 return id;
406 *theStream << " -b " << aBeginLine;407}
407 if (aEndLine)408
408 *theStream << " -e " << aEndLine;409std::size_t
409 *theStream << '\0';410DebuggerClientImpl::typemap_get()
410 theStream->sync();411{
411 return id;412 std::size_t id = ++theLastId;
412 }413 *theOutStream << "typemap_get -i " << id << '\0';
413 414 theOutStream->flush();
414 std::size_t DebuggerClientImpl::stream_option(OutputStream aStream, StreamBehaviour aBehaviour)415 return id;
415 {416}
416 std::size_t id = ++theLastId;417
417 switch (aStream) {418std::size_t
418 case Stdout:419DebuggerClientImpl::property_get(
419 *theStream << "stdout";420 const std::string& aPropertyLongName,
420 break;421 int aStackDepth,
421 case Stderr:422 int aContextId,
422 *theStream << "stderr";423 std::size_t aMaxDataSize,
423 break;424 int aDatapage,
424 case Stdin:425 const std::string& aPropertyKey)
425 *theStream << "stdin";426{
426 break;427 std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
427 }428 if (aDatapage >= 0)
428 *theStream << " -i " << id << " -c ";429 *theOutStream << " -p " << aDatapage;
429 switch (aBehaviour) {430 if (aPropertyKey != "")
430 case Disable:431 *theOutStream << " -k " << aPropertyKey;
431 *theStream << "0";432 *theOutStream << '\0';
432 break;433 theOutStream->flush();
433 case CopyData:434 return id;
434 *theStream << "1";435}
435 break;436
436 case Redirection:437std::size_t
437 *theStream << "2";438DebuggerClientImpl::property_set(
438 break;439 const std::string& aPropertyLongName,
439 }440 int aStackDepth,
440 *theStream << '\0';441 int aContextId,
441 theStream->sync();442 std::size_t aMaxDataSize,
442 return id;443 const std::string& aPropertyAddress)
443 }444{
444 445 std::size_t id = property_x("property_set", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
445 std::size_t DebuggerClientImpl::do_break()446 if (aPropertyAddress != "")
446 {447 *theOutStream << " -a " << aPropertyAddress;
447 std::size_t id = ++theLastId;448 *theOutStream << '\0';
448 *theStream << "break -i " << id << '\0';449 theOutStream->flush();
449 theStream->sync();450 return id;
450 return id;451}
451 }452
452 453std::size_t
453 std::size_t DebuggerClientImpl::eval(std::string const &aExpr)454DebuggerClientImpl::property_value(
454 {455 const std::string& aPropertyLongName,
455 std::size_t id = ++theLastId;456 int aStackDepth,
456 *theStream << "eval -i " << id << " -- " << encoding::Base64::encode(aExpr.c_str()) << '\0';457 int aContextId,
457 theStream->sync();458 std::size_t aMaxDataSize,
458 return id;459 int aDatapage,
459 }460 const std::string& aPropertyKey,
460 461 const std::string& aPropertyAddress)
461 void DebuggerClientImpl::quit() {462{
462 theListener.stopLooping();463 std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize);
463 theListener.join();464 if (aDatapage >= 0)
464 }465 *theOutStream << " -p " << aDatapage;
465 466 if (aPropertyKey != "")
466 467 *theOutStream << " -k " << aPropertyKey;
467 468 if (aPropertyAddress != "")
468 DebuggerClientImpl::~DebuggerClientImpl()469 *theOutStream << " -a " << aPropertyAddress;
469 {470 *theOutStream << '\0';
470 if (theListener.status() == DebuggerListener::RUNNING) {471 theOutStream->flush();
471 theListener.stopLooping();472 return id;
472 theListener.join();473}
473 }474
474 if (theSocket) {475std::size_t
475 theSocket->close();476DebuggerClientImpl::property_x(
476 theSocket->cleanUp();477 const std::string& aCommand,
477 delete theSocket;478 const std::string& aPropertyLongName,
478 }479 int aStackDepth,
479 if (theStream) {480 int aContextId,
480 theStream->sync();481 std::size_t aMaxDataSize)
481 delete theStream;482{
482 delete theStreamBuffer;483 std::size_t id = ++theLastId;
483 }484 *theOutStream << aCommand << " -i " << id << " -n " << aPropertyLongName;
484 }485 if (aStackDepth > 0)
485}486 *theOutStream << " -d " << aStackDepth;
487 if (aContextId > 0)
488 *theOutStream << " -c " << aContextId;
489 if (aMaxDataSize > 0)
490 *theOutStream << " -m " << aMaxDataSize;
491 theOutStream->flush();
492 return id;
493}
494
495std::size_t
496DebuggerClientImpl::source(
497 std::string const &aFile,
498 unsigned int aBeginLine,
499 unsigned int aEndLine)
500{
501 std::size_t id = ++theLastId;
502 *theOutStream << "source -i " << id;
503 // enable zorba extensions
504 *theOutStream << " -z 1";
505 *theOutStream << " -f \"" << aFile << "\"";
506 if (aBeginLine)
507 *theOutStream << " -b " << aBeginLine;
508 if (aEndLine)
509 *theOutStream << " -e " << aEndLine;
510 *theOutStream << '\0';
511 theOutStream->flush();
512 return id;
513}
514
515std::size_t
516DebuggerClientImpl::stream_option(OutputStream aStream, StreamBehaviour aBehaviour)
517{
518 std::size_t id = ++theLastId;
519 switch (aStream) {
520 case Stdout:
521 *theOutStream << "stdout";
522 break;
523 case Stderr:
524 *theOutStream << "stderr";
525 break;
526 case Stdin:
527 *theOutStream << "stdin";
528 break;
529 }
530 *theOutStream << " -i " << id << " -c ";
531 switch (aBehaviour) {
532 case Disable:
533 *theOutStream << "0";
534 break;
535 case CopyData:
536 *theOutStream << "1";
537 break;
538 case Redirection:
539 *theOutStream << "2";
540 break;
541 }
542 *theOutStream << '\0';
543 theOutStream->flush();
544 return id;
545}
546
547std::size_t
548DebuggerClientImpl::do_break()
549{
550 std::size_t id = ++theLastId;
551 *theOutStream << "break -i " << id << '\0';
552 theOutStream->flush();
553 return id;
554}
555
556std::size_t
557DebuggerClientImpl::eval(std::string const &aExpr)
558{
559 std::size_t id = ++theLastId;
560 *theOutStream << "eval -i " << id << " -- " << encoding::Base64::encode(aExpr.c_str()) << '\0';
561 theOutStream->flush();
562 return id;
563}
564
565void
566DebuggerClientImpl::quit()
567{
568 theListener->stopLooping();
569 theListener->join();
570}
571
572} // namespace zorba
486573
=== modified file 'src/debugger/debugger_clientimpl.h'
--- src/debugger/debugger_clientimpl.h 2011-07-01 01:53:24 +0000
+++ src/debugger/debugger_clientimpl.h 2011-12-20 18:15:30 +0000
@@ -13,7 +13,8 @@
13 * See the License for the specific language governing permissions and13 * See the License for the specific language governing permissions and
14 * limitations under the License.14 * limitations under the License.
15 */15 */
16#pragma once16#ifndef ZORBA_DEBUGGER_CLIENTIMPL_H
17#define ZORBA_DEBUGGER_CLIENTIMPL_H
1718
18#include <string>19#include <string>
19#include <zorba/debugger_client.h>20#include <zorba/debugger_client.h>
@@ -21,7 +22,7 @@
21#include "zorbautils/runnable.h"22#include "zorbautils/runnable.h"
2223
23namespace zorba {24namespace zorba {
24 class socket_streambuf;25 class SocketStreambuf;
25 class DebuggerEventHandler;26 class DebuggerEventHandler;
26 class DebuggerListener;27 class DebuggerListener;
27 class DebuggerClientImpl;28 class DebuggerClientImpl;
@@ -48,6 +49,7 @@
48 public: // API49 public: // API
49 virtual void accept();50 virtual void accept();
50 virtual std::size_t status();51 virtual std::size_t status();
52 virtual std::size_t variables();
51 virtual std::size_t feature_get(const std::string& aFeatureName);53 virtual std::size_t feature_get(const std::string& aFeatureName);
52 virtual std::size_t feature_set(const std::string& aFeatureName,54 virtual std::size_t feature_set(const std::string& aFeatureName,
53 const std::string& aValue);55 const std::string& aValue);
@@ -110,12 +112,17 @@
110 int aContextId = -1,112 int aContextId = -1,
111 std::size_t aMaxDataSize = 0);113 std::size_t aMaxDataSize = 0);
112 private:114 private:
113 TCPServerSocket theServerSocket;115 TCPServerSocket theServerSocket;
114 TCPSocket* theSocket;116 TCPSocket* theSocket;
115 socket_streambuf* theStreamBuffer;117 SocketStreambuf* theInStreamBuffer;
116 std::iostream* theStream;118 SocketStreambuf* theOutStreamBuffer;
119 std::istream* theInStream;
120 std::ostream* theOutStream;
117 DebuggerEventHandler* theHandler;121 DebuggerEventHandler* theHandler;
118 DebuggerListener theListener;122 DebuggerListener* theListener;
119 std::size_t theLastId;123 std::size_t theLastId;
120 };124 };
121}125
126} // namespace zorba
127
128#endif // ZORBA_DEBUGGER_CLIENTIMPL_H
122129
=== modified file 'src/debugger/debugger_common.h'
--- src/debugger/debugger_common.h 2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_common.h 2011-12-20 18:15:30 +0000
@@ -20,22 +20,15 @@
20#include "common/common.h"20#include "common/common.h"
2121
22/* Type definitions */22/* Type definitions */
23typedef unsigned char StepCommand;
24typedef unsigned char ExecutionStatus;23typedef unsigned char ExecutionStatus;
25typedef unsigned short SuspensionCause;24typedef unsigned short SuspensionCause;
2625
27/* Kind of step command */
28const StepCommand STEP_INTO = 0x01;
29const StepCommand STEP_OUT = 0x02;
30const StepCommand STEP_OVER = 0x03;
31
32/* Status of the engine */26/* Status of the engine */
33const ExecutionStatus QUERY_IDLE = 0x01;27const ExecutionStatus QUERY_IDLE = 0x01;
34const ExecutionStatus QUERY_RUNNING = 0x02;28const ExecutionStatus QUERY_RUNNING = 0x02;
35const ExecutionStatus QUERY_RESUMED = 0x03;29const ExecutionStatus QUERY_SUSPENDED = 0x03;
36const ExecutionStatus QUERY_SUSPENDED = 0x04;30const ExecutionStatus QUERY_TERMINATED = 0x04;
37const ExecutionStatus QUERY_TERMINATED = 0x05;31const ExecutionStatus QUERY_DETACHED = 0x05;
38const ExecutionStatus QUERY_DETACHED = 0x06;
3932
40/* Cause of the suspension of the engine */33/* Cause of the suspension of the engine */
41const SuspensionCause CAUSE_USER = 0x01;34const SuspensionCause CAUSE_USER = 0x01;
4235
=== modified file 'src/debugger/debugger_commons.cpp'
--- src/debugger/debugger_commons.cpp 2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_commons.cpp 2011-12-20 18:15:30 +0000
@@ -151,13 +151,11 @@
151 theBreakCondition(0),151 theBreakCondition(0),
152 theExecEval(false),152 theExecEval(false),
153 theStepping(false)153 theStepping(false)
154
155{154{
156 theRuntime = NULL;155 theRuntime = NULL;
157 theCurrentStaticContext = NULL;156 theCurrentStaticContext = NULL;
158 theCurrentDynamicContext = NULL;157 theCurrentDynamicContext = NULL;
159 thePlanState = NULL;158 thePlanState = NULL;
160 theDebugIteratorState = NULL;
161}159}
162160
163DebuggerCommons::~DebuggerCommons()161DebuggerCommons::~DebuggerCommons()
@@ -185,8 +183,6 @@
185183
186 if(ar.is_serializing_out())184 if(ar.is_serializing_out())
187 thePlanState = NULL;185 thePlanState = NULL;
188 if(ar.is_serializing_out())
189 theDebugIteratorState = NULL;
190 ar & theEvalItem;186 ar & theEvalItem;
191 ar & theExecEval;187 ar & theExecEval;
192 ar & theStepping;188 ar & theStepping;
@@ -230,17 +226,98 @@
230}226}
231227
232unsigned int228unsigned int
233DebuggerCommons::addBreakpoint(const QueryLoc& aLocation, bool aEnabled)229DebuggerCommons::addBreakpoint(String& aFileName, int aLine, bool aEnabled)
234{230{
235 BreakableIdMap::iterator lIter = theBreakableIDs.find(aLocation);231 QueryLoc lLocation;
232 lLocation.setLineBegin(aLine);
233 lLocation.setLineEnd(aLine);
234 lLocation.setFilename(aFileName.c_str());
235
236 // we make sure that the this location file name is aligned with the internal ones
237 // it must have a valid URI and a scheme (file://, http://, or https://)
238 adjustLocationFilePath(lLocation);
239
240 BreakableIdMap::iterator lIter = theBreakableIDs.find(lLocation);
241 unsigned int lId;
236242
237 if (lIter == theBreakableIDs.end()) {243 if (lIter == theBreakableIDs.end()) {
244 String lFileName = aFileName;
245 // be prepared to throw an exception
238 std::stringstream lSs;246 std::stringstream lSs;
239 lSs << "The breakpoint could not be set at line " << aLocation.getLineBegin()247 lSs << "The breakpoint could not be set at line " << aLine
240 << " in file: " << aLocation.getFilename();248 << " in file \"" << lFileName << "\"";
241 throw lSs.str();249
242 }250 // let us then try some search before we fail, be good to the user and help him
243 unsigned int lId = lIter->second;251 // 1. first we check if he sent a file URI; in this case, sorry!
252 if (lFileName.find("file://") == 0) {
253 throw lSs.str();
254 }
255
256 // now we have to normalize if we hope to find something
257 lFileName = URIHelper::encodeFileURI(lFileName).str();
258 // remove the added file schema prefix
259 // TODO: maybe there is a better way to do this encoding
260 lFileName = lFileName.substr(8);
261
262 // 2. secondly we hope he gave us part of a path of a file
263 lIter = theBreakableIDs.begin();
264 String::size_type lFileNameSize = lFileName.size();
265 std::vector<std::pair<QueryLoc, int> > lFoundBreakables;
266 zorba::String lFirstBreakablePath;
267 while (lIter != theBreakableIDs.end()) {
268 // for now, only valid if on the breakable is on the same line as requested
269 // TODO: this could be improved if the user wants to add a breakpoint to a line
270 // INSIDE a breakable that spans over multiple lines
271 if (lIter->second != theMainModuleBreakableId && lIter->first.getLineBegin() == aLine) {
272 zorba::String lBreakablePath = lIter->first.getFilename().str();
273
274 // dies the given string matche any part in the breakable file name?
275 if (lBreakablePath.find(lFileName) != String::npos) {
276 // we found the fist candidate path
277 if (lFirstBreakablePath == "") {
278 lFirstBreakablePath = lBreakablePath;
279 }
280 // but stop as soon as we are reaching a second different path (report ambiguity)
281 else if (lFirstBreakablePath != lBreakablePath){
282 lSs.str("");
283 lSs << "The file name \"" << aFileName << "\" is ambiguous. "
284 << "I already found two potential files to set a breakpoint in line " << aLine
285 << ":" << std::endl << " " << lFirstBreakablePath << std::endl << " " << lBreakablePath;
286 throw lSs.str();
287 }
288
289 // Yes! We found one!
290 lFoundBreakables.push_back(std::pair<QueryLoc, int>(lIter->first, lIter->second));
291 }
292 }
293 lIter++;
294 }
295
296 // what should I say, not a very successful search :(
297 if (lFoundBreakables.size() == 0) {
298 throw lSs.str();
299 }
300
301 // TODO: The best solution would be for the debugger to enable all the
302 // matched breakables but the protocol can send back only one ID of the
303 // breakpoint set.
304
305 // so we have multiple breakables, get the first in line
306 // TODO: this does not catch multiple breakables starting in the same line
307 // so only one will be picked (depending how the translator generated them)
308 unsigned int lMinCol = lFoundBreakables.at(0).first.getColumnBegin();
309 lId = lFoundBreakables.at(0).second;
310 for (std::size_t i = 1; i < lFoundBreakables.size(); i++) {
311 if (lMinCol > lFoundBreakables.at(i).first.getColumnBegin()) {
312 lId = lFoundBreakables.at(i).second;
313 }
314 }
315 }
316 else {
317 lId = lIter->second;
318 }
319
320 // now we have a breakable, so set it accordingly
244 theBreakables[lId].setSet(true);321 theBreakables[lId].setSet(true);
245 theBreakables[lId].setEnabled(aEnabled);322 theBreakables[lId].setEnabled(aEnabled);
246 return lId;323 return lId;
@@ -253,6 +330,12 @@
253 return theBreakables[aId];330 return theBreakables[aId];
254}331}
255332
333BreakableVector
334DebuggerCommons::getBreakpoints()
335{
336 return theBreakables;
337}
338
256void339void
257DebuggerCommons::checkBreakpoint(unsigned int aId)340DebuggerCommons::checkBreakpoint(unsigned int aId)
258{341{
@@ -338,6 +421,7 @@
338bool421bool
339DebuggerCommons::hasToBreakAt(QueryLoc aLocation)422DebuggerCommons::hasToBreakAt(QueryLoc aLocation)
340{423{
424 // we make sure that this location file name is a valid URI and has a scheme (file://, http://, or https://)
341 adjustLocationFilePath(aLocation);425 adjustLocationFilePath(aLocation);
342426
343 BreakableIdMap::const_iterator lIter = theBreakableIDs.find(aLocation);427 BreakableIdMap::const_iterator lIter = theBreakableIDs.find(aLocation);
@@ -449,14 +533,6 @@
449 ZORBA_ASSERT(thePlanState == aPlanState);533 ZORBA_ASSERT(thePlanState == aPlanState);
450}534}
451535
452void
453DebuggerCommons::setDebugIteratorState(DebugIteratorState* aState)
454{
455 theDebugIteratorState = aState;
456 //Check postconditions
457 ZORBA_ASSERT(theDebugIteratorState == aState);
458}
459
460std::list<std::pair<zstring, zstring> >536std::list<std::pair<zstring, zstring> >
461DebuggerCommons::eval(const zstring& aExpr, Zorba_SerializerOptions& aSerOpts)537DebuggerCommons::eval(const zstring& aExpr, Zorba_SerializerOptions& aSerOpts)
462{538{
@@ -511,11 +587,17 @@
511}587}
512588
513void589void
514DebuggerCommons::addBreakable(Breakable& aBreakable)590DebuggerCommons::addBreakable(
591 Breakable& aBreakable,
592 bool aIsMainModuleBreakable)
515{593{
594 // we make sure that this breakable file name is a valid URI and has a scheme (file://, http://, or https://)
516 adjustLocationFilePath(aBreakable.getLocation());595 adjustLocationFilePath(aBreakable.getLocation());
517596
518 unsigned int lId = theBreakables.size();597 unsigned int lId = theBreakables.size();
598 if (aIsMainModuleBreakable) {
599 theMainModuleBreakableId = lId;
600 }
519 theBreakables.push_back(aBreakable);601 theBreakables.push_back(aBreakable);
520 theBreakableIDs[aBreakable.getLocation()] = lId;602 theBreakableIDs[aBreakable.getLocation()] = lId;
521}603}
@@ -523,6 +605,9 @@
523void605void
524DebuggerCommons::pushStackFrame(QueryLoc aLocation, std::string& aFunctionName)606DebuggerCommons::pushStackFrame(QueryLoc aLocation, std::string& aFunctionName)
525{607{
608 // we make sure that the stack frame locations always have valid URIs and a scheme (file://, http://, or https://)
609 adjustLocationFilePath(aLocation);
610
526 theStackTrace.push_back(std::pair<QueryLoc, std::string>(aLocation, aFunctionName));611 theStackTrace.push_back(std::pair<QueryLoc, std::string>(aLocation, aFunctionName));
527}612}
528613
@@ -541,11 +626,24 @@
541void626void
542DebuggerCommons::adjustLocationFilePath(QueryLoc& aLocation)627DebuggerCommons::adjustLocationFilePath(QueryLoc& aLocation)
543{628{
544 if (aLocation.getFilename().substr(0, 7) == "file://") {629 zstring lOldFilename(aLocation.getFilename());
545 // adjust the file paths by removing the schema and encoding630 zstring lPrefix = lOldFilename.substr(0, 7);
546 zstring lOldFilename(aLocation.getFilename());631
632 if (lPrefix == "file://") {
633#ifdef WIN32
634 // decode and encode back to solve the driver column encoding: C:, D:, etc.
547 const String lNewFilename = URIHelper::decodeFileURI(lOldFilename.str());635 const String lNewFilename = URIHelper::decodeFileURI(lOldFilename.str());
548 aLocation.setFilename(lNewFilename.str());636 const String lNewURI = URIHelper::encodeFileURI(lNewFilename);
637 aLocation.setFilename(lNewURI.str());
638#endif
639 return;
640 }
641
642 // just encode and assume file for non-URI locations
643 if (lPrefix != "http://" && lPrefix != "https:/") {
644 const String lNewURI = URIHelper::encodeFileURI(lOldFilename.str());
645 aLocation.setFilename(lNewURI.str());
646 return;
549 }647 }
550}648}
551649
552650
=== modified file 'src/debugger/debugger_commons.h'
--- src/debugger/debugger_commons.h 2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_commons.h 2011-12-20 18:15:30 +0000
@@ -19,14 +19,17 @@
19#include <map>19#include <map>
20#include <string>20#include <string>
2121
22#include <zorba/util/uri.h>
23#include <zorba/zorba_string.h>
24
22#include "compiler/parser/query_loc.h"25#include "compiler/parser/query_loc.h"
23#include "runtime/core/item_iterator.h"26#include "runtime/core/item_iterator.h"
2427
25#include "zorbaserialization/serialization_engine.h"28#include "zorbaserialization/serialization_engine.h"
26#include "zorbatypes/zstring.h"29#include "zorbatypes/zstring.h"
2730
28#include "debugger/debugger_common.h"31#include "debugger_common.h"
29#include "debugger/query_locationimpl.h"32#include "query_locationimpl.h"
3033
3134
32struct Zorba_SerializerOptions;35struct Zorba_SerializerOptions;
@@ -208,16 +211,6 @@
208 void setPlanState(PlanState* aPlanState);211 void setPlanState(PlanState* aPlanState);
209212
210 /**213 /**
211 * @brief Sets the current debugger state.
212 *
213 * When the debugger suspends, it saves its state.
214 *
215 * @param aState a pointer to the current debugger state.
216 * @post aState == theDebugIteratorState
217 */
218 void setDebugIteratorState(DebugIteratorState* aState);
219
220 /**
221 * @brief Sets a setpoint according to the step out rules.214 * @brief Sets a setpoint according to the step out rules.
222 *215 *
223 * This method sets a breakpoint according to the rules according to216 * This method sets a breakpoint according to the rules according to
@@ -245,11 +238,14 @@
245 public:238 public:
246239
247 unsigned int240 unsigned int
248 addBreakpoint(const QueryLoc& location, bool enabled);241 addBreakpoint(String& fileName, int line, bool enabled);
249242
250 Breakable243 Breakable
251 getBreakpoint(unsigned int id);244 getBreakpoint(unsigned int id);
252245
246 BreakableVector
247 getBreakpoints();
248
253 void249 void
254 updateBreakpoint(unsigned int id, bool enabled);250 updateBreakpoint(unsigned int id, bool enabled);
255251
@@ -336,7 +332,7 @@
336 std::string getFilepathOfURI(const std::string& aUri) const;332 std::string getFilepathOfURI(const std::string& aUri) const;
337333
338 void334 void
339 addBreakable(Breakable& location);335 addBreakable(Breakable& location, bool isMainModuleBreakable = false);
340336
341 void337 void
342 pushStackFrame(QueryLoc location, std::string& functionName);338 pushStackFrame(QueryLoc location, std::string& functionName);
@@ -384,10 +380,10 @@
384 std::vector<DebugIterator*> theIteratorStack;380 std::vector<DebugIterator*> theIteratorStack;
385 std::size_t theBreakCondition;381 std::size_t theBreakCondition;
386 PlanState* thePlanState;382 PlanState* thePlanState;
387 DebugIteratorState* theDebugIteratorState;
388 store::Item_t theEvalItem;383 store::Item_t theEvalItem;
389 bool theExecEval;384 bool theExecEval;
390 bool theStepping;385 bool theStepping;
386 unsigned int theMainModuleBreakableId;
391 };387 };
392388
393}389}
394390
=== modified file 'src/debugger/debugger_communicator.cpp'
--- src/debugger/debugger_communicator.cpp 2011-07-29 23:01:30 +0000
+++ src/debugger/debugger_communicator.cpp 2011-12-20 18:15:30 +0000
@@ -77,15 +77,15 @@
77void77void
78DebuggerCommunicator::connect()78DebuggerCommunicator::connect()
79{79{
80 for (int i = 0; i < 3 && !theSocket; i++)80 for (int i = 0; i < 5 && !theSocket; i++)
81 {81 {
82 try82 try
83 {83 {
84 // Connect to the client on the given host and port84 // Connect to the client on the given host and port
85 std::auto_ptr<TCPSocket> lSocket(new TCPSocket(theHost, thePort));85 std::auto_ptr<TCPSocket> lSocket(new TCPSocket(theHost, thePort));
86 theSocket = lSocket.release();86 theSocket = lSocket.release();
87 theSocketInStream = new socket_streambuf(*theSocket);87 theSocketInStream = new SocketStreambuf(*theSocket);
88 theSocketOutStream = new socket_streambuf(*theSocket);88 theSocketOutStream = new SocketStreambuf(*theSocket);
89 theCommunicatorInStream = new std::istream(theSocketInStream);89 theCommunicatorInStream = new std::istream(theSocketInStream);
90 theCommunicatorOutStream = new std::ostream(theSocketOutStream);90 theCommunicatorOutStream = new std::ostream(theSocketOutStream);
91 theResponseQueue = new ResponseQueue(theCommunicatorOutStream);91 theResponseQueue = new ResponseQueue(theCommunicatorOutStream);
9292
=== modified file 'src/debugger/debugger_communicator.h'
--- src/debugger/debugger_communicator.h 2011-07-01 16:07:54 +0000
+++ src/debugger/debugger_communicator.h 2011-12-20 18:15:30 +0000
@@ -28,7 +28,7 @@
28namespace zorba {28namespace zorba {
2929
30class TCPSocket;30class TCPSocket;
31class socket_streambuf;31class SocketStreambuf;
3232
33class DebuggerCommunicator {33class DebuggerCommunicator {
3434
@@ -96,13 +96,13 @@
96 96
9797
98 TCPSocket* theSocket;98 TCPSocket* theSocket;
99 socket_streambuf* theSocketInStream;99 SocketStreambuf* theSocketInStream;
100 socket_streambuf* theSocketOutStream;100 SocketStreambuf* theSocketOutStream;
101 std::istream* theCommunicatorInStream;101 std::istream* theCommunicatorInStream;
102 std::ostream* theCommunicatorOutStream;102 std::ostream* theCommunicatorOutStream;
103 ResponseQueue* theResponseQueue;103 ResponseQueue* theResponseQueue;
104};104};
105105
106}//end of namespace106} //namespace zorba
107107
108#endif // ZORBA_DEBUGGER_COMMUNICATOR_H108#endif // ZORBA_DEBUGGER_COMMUNICATOR_H
109109
=== modified file 'src/debugger/debugger_protocol.cpp'
--- src/debugger/debugger_protocol.cpp 2011-06-22 11:19:07 +0000
+++ src/debugger/debugger_protocol.cpp 2011-12-20 18:15:30 +0000
@@ -28,25 +28,17 @@
28DebuggerCommand::DebuggerCommand(std::string& aCommand)28DebuggerCommand::DebuggerCommand(std::string& aCommand)
29 : theData()29 : theData()
30{30{
31 // this implements the DBGP command specification:
32 // http://xdebug.org/docs-dbgp.php#ide-to-debugger-engine-communications
33
34 // the debugger client should only send space delimited command
35 // and arguments, therefore we only check for space character
31 std::size_t lNameEnd = aCommand.find(" ");36 std::size_t lNameEnd = aCommand.find(" ");
37
38 // first whitespace delimited token is the command name
32 theName = aCommand.substr(0, lNameEnd);39 theName = aCommand.substr(0, lNameEnd);
33 std::size_t lDataBegin = aCommand.find("--", lNameEnd);
34 std::string lArgs = aCommand.substr(lNameEnd + 1, lDataBegin);
3540
36 if (lDataBegin != std::string::npos) {41 std::string lArgs = aCommand.substr(lNameEnd + 1);
37 lDataBegin += 2;
38 while (lDataBegin < aCommand.size()) {
39 switch (aCommand.at(lDataBegin)) {
40 case ' ':
41 case '\t':
42 ++lDataBegin;
43 continue;
44 default:
45 theData = aCommand.substr(lDataBegin);
46 lDataBegin = aCommand.size();
47 }
48 }
49 }
5042
51 bool lFollowsArg = true;43 bool lFollowsArg = true;
52 bool lInArgName = false;44 bool lInArgName = false;
@@ -74,6 +66,26 @@
74 lInArgName = true;66 lInArgName = true;
75 continue;67 continue;
76 }68 }
69 // we found the encoded data in this message
70 if (lArgName.str() == "") {
71 // DBGP is fuzzy here: can there be whitespaces between "--" and the encoded data?
72 // so, tollerate the whitespaces before data starts
73 std::string::size_type lDataBegin = i + 1;
74 while (++i < lArgs.size()) {
75 switch (lArgs.at(i)) {
76 case ' ':
77 case '\t':
78 continue;
79 default:
80 lDataBegin = i;
81 // force the while to terminate
82 i = lArgs.size();
83 }
84 }
85
86 theData = lArgs.substr(lDataBegin);
87 }
88
77 default:89 default:
78 if (!lInArgName) {90 if (!lInArgName) {
79 throw "error reading command";91 throw "error reading command";
8092
=== modified file 'src/debugger/debugger_runtime.cpp'
--- src/debugger/debugger_runtime.cpp 2011-08-03 02:26:53 +0000
+++ src/debugger/debugger_runtime.cpp 2011-12-20 18:15:30 +0000
@@ -21,6 +21,7 @@
21#include <memory>21#include <memory>
22#include <vector>22#include <vector>
23#include <sstream>23#include <sstream>
24#include <iomanip>
24#include <fstream>25#include <fstream>
2526
26#include <zorba/util/uri.h>27#include <zorba/util/uri.h>
@@ -70,7 +71,8 @@
70 thePlanIsOpen(false),71 thePlanIsOpen(false),
71 theSerializer(0),72 theSerializer(0),
72 theItemHandler(aHandler),73 theItemHandler(aHandler),
73 theCallbackData(aCallBackData)74 theCallbackData(aCallBackData),
75 theLastContinuationCommand()
74{76{
75}77}
7678
@@ -122,7 +124,7 @@
122DebuggerRuntime::runQuery()124DebuggerRuntime::runQuery()
123{125{
124 theLock.wlock();126 theLock.wlock();
125 theExecStatus = theExecStatus == QUERY_SUSPENDED ? QUERY_RESUMED : QUERY_RUNNING;127 theExecStatus = QUERY_RUNNING;
126128
127 try {129 try {
128 DebuggerCommons* lCommons = getDebbugerCommons();130 DebuggerCommons* lCommons = getDebbugerCommons();
@@ -144,33 +146,23 @@
144 theOStream.flush();146 theOStream.flush();
145 } catch (FlowCtlException&) {147 } catch (FlowCtlException&) {
146 // Runtime correctly terminated by user interrupt148 // Runtime correctly terminated by user interrupt
147 } catch (ZorbaException const& e){149 } catch (ZorbaException const& e) {
148 // this does not rethrow but only print the error message150 std::cerr << e << std::endl;
149 ZorbaImpl::notifyError(theQuery->theDiagnosticHandler, e);
150 }151 }
151 theLock.wlock();152 theLock.wlock();
152 theExecStatus = QUERY_TERMINATED;153 theExecStatus = QUERY_TERMINATED;
153 theLock.unlock();154 theLock.unlock();
154}155}
155156
156
157void
158DebuggerRuntime::setQueryRunning()
159{
160 AutoLock lLock(theLock, Lock::WRITE);
161 assert(theExecStatus == QUERY_RESUMED);
162 theExecStatus = QUERY_RUNNING;
163}
164
165// ****************************************************************************157// ****************************************************************************
166// Breakpoints158// Breakpoints
167159
168unsigned int160unsigned int
169DebuggerRuntime::addBreakpoint(const QueryLoc& aLocation, bool aEnabled)161DebuggerRuntime::addBreakpoint(String& aFileName, int aLine, bool aEnabled)
170{162{
171 AutoLock lLock(theLock, Lock::WRITE);163 AutoLock lLock(theLock, Lock::WRITE);
172 DebuggerCommons* lCommons = getDebbugerCommons();164 DebuggerCommons* lCommons = getDebbugerCommons();
173 return lCommons->addBreakpoint(aLocation, aEnabled);165 return lCommons->addBreakpoint(aFileName, aLine, aEnabled);
174}166}
175167
176Breakable168Breakable
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches