Merge lp:~zorba-coders/zorba/debugger_client into lp:zorba
- debugger_client
- Merge into trunk
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 | ||||||||||||||||||||||||||||||||
Related bugs: |
|
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.
Gabriel Petrovay (gabipetrovay) : | # |
Gabriel Petrovay (gabipetrovay) wrote : | # |
Use the conversation "Can we please have libedit on the build server?" for opinions about ZORBA_WITH_
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
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/
Validation queue job debugger_
The final status was:
No tests were run - build or configure step must have failed.
Not commiting changes.
Error in read script: /home/ceej/
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
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/
Validation queue job debugger_
The final status was:
1 tests did not succeed - changes not commited.
Error in read script: /home/ceej/
- 10593. By Gabriel Petrovay
-
added missing version and xquery version from the dbgp-message-
handler. xq module
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue starting for merge proposal.
Log at: http://
Zorba Build Bot (zorba-buildbot) wrote : | # |
Validation queue job debugger_
All tests succeeded!
Preview Diff
1 | === modified file 'CMakeConfiguration.txt' | |||
2 | --- CMakeConfiguration.txt 2011-09-16 19:55:59 +0000 | |||
3 | +++ CMakeConfiguration.txt 2011-12-20 18:15:30 +0000 | |||
4 | @@ -70,10 +70,6 @@ | |||
5 | 70 | SET(ZORBA_FOR_ONE_THREAD_ONLY OFF CACHE BOOL "compile zorba for single threaded use") | 70 | SET(ZORBA_FOR_ONE_THREAD_ONLY OFF CACHE BOOL "compile zorba for single threaded use") |
6 | 71 | MESSAGE(STATUS "ZORBA_FOR_ONE_THREAD_ONLY: " ${ZORBA_FOR_ONE_THREAD_ONLY}) | 71 | MESSAGE(STATUS "ZORBA_FOR_ONE_THREAD_ONLY: " ${ZORBA_FOR_ONE_THREAD_ONLY}) |
7 | 72 | 72 | ||
8 | 73 | # by default the zorba command line client is deactivated until it gets to a more stable and userfriendly state | ||
9 | 74 | SET(ZORBA_WITH_DEBUGGER_CLIENT OFF CACHE BOOL "build and install zorbas command line debugger client") | ||
10 | 75 | MESSAGE(STATUS "ZORBA_WITH_DEBUGGER_CLIENT: " ${ZORBA_WITH_DEBUGGER_CLIENT}) | ||
11 | 76 | |||
12 | 77 | IF (DEFINED UNIX) | 73 | IF (DEFINED UNIX) |
13 | 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) |
14 | 79 | MESSAGE(FATAL_ERROR "pthread is not available") | 75 | MESSAGE(FATAL_ERROR "pthread is not available") |
15 | @@ -93,6 +89,13 @@ | |||
16 | 93 | SET(ZORBA_WITH_DEBUGGER ON CACHE BOOL "compile zorba with debugger support") | 89 | SET(ZORBA_WITH_DEBUGGER ON CACHE BOOL "compile zorba with debugger support") |
17 | 94 | MESSAGE(STATUS "ZORBA_WITH_DEBUGGER [ON/OFF]: " ${ZORBA_WITH_DEBUGGER}) | 90 | MESSAGE(STATUS "ZORBA_WITH_DEBUGGER [ON/OFF]: " ${ZORBA_WITH_DEBUGGER}) |
18 | 95 | 91 | ||
19 | 92 | SET(ZORBA_WITH_DEBUGGER_CLIENT ON CACHE BOOL "compile zorba with a command line debugger client") | ||
20 | 93 | MESSAGE(STATUS "ZORBA_WITH_DEBUGGER_CLIENT [ON/OFF]: " ${ZORBA_WITH_DEBUGGER_CLIENT}) | ||
21 | 94 | |||
22 | 95 | IF (ZORBA_WITH_DEBUGGER_CLIENT AND NOT ZORBA_WITH_DEBUGGER) | ||
23 | 96 | MESSAGE(FATAL_ERROR "Can not build a debugger client if the debugger support is disabled. Turn on ZORBA_WITH_DEBUGGER") | ||
24 | 97 | ENDIF (ZORBA_WITH_DEBUGGER_CLIENT AND NOT ZORBA_WITH_DEBUGGER) | ||
25 | 98 | |||
26 | 96 | SET(ZORBA_TEST_TIMEOUT_VALUE 60 CACHE INTEGER "default test timeout value") | 99 | SET(ZORBA_TEST_TIMEOUT_VALUE 60 CACHE INTEGER "default test timeout value") |
27 | 97 | MESSAGE(STATUS "ZORBA_TEST_TIMEOUT_VALUE: " ${ZORBA_TEST_TIMEOUT_VALUE}) | 100 | MESSAGE(STATUS "ZORBA_TEST_TIMEOUT_VALUE: " ${ZORBA_TEST_TIMEOUT_VALUE}) |
28 | 98 | 101 | ||
29 | 99 | 102 | ||
30 | === modified file 'bin/CMakeLists.txt' | |||
31 | --- bin/CMakeLists.txt 2011-11-04 11:40:20 +0000 | |||
32 | +++ bin/CMakeLists.txt 2011-12-20 18:15:30 +0000 | |||
33 | @@ -15,26 +15,29 @@ | |||
34 | 15 | INCLUDE_DIRECTORIES(AFTER ${CMAKE_SOURCE_DIR}/src/) | 15 | INCLUDE_DIRECTORIES(AFTER ${CMAKE_SOURCE_DIR}/src/) |
35 | 16 | INCLUDE_DIRECTORIES(AFTER ${CMAKE_CURRENT_SOURCE_DIR}) | 16 | INCLUDE_DIRECTORIES(AFTER ${CMAKE_CURRENT_SOURCE_DIR}) |
36 | 17 | 17 | ||
51 | 18 | IF(ZORBA_WITH_DEBUGGER_CLIENT) | 18 | IF (ZORBA_WITH_DEBUGGER_CLIENT) |
52 | 19 | CONFIGURE_FILE (debug_client/event_handler_init.cpp.in debug_client/event_handler_init.cpp) | 19 | IF (NOT WIN32) |
53 | 20 | 20 | FIND_PACKAGE (Libedit) | |
54 | 21 | SET(DEBUG_CLIENT_SRCS | 21 | IF (LIBEDIT_FOUND) |
55 | 22 | debug_client/tuple.h | 22 | INCLUDE_DIRECTORIES (${LIBEDIT_INCLUDE_DIRS}) |
56 | 23 | debug_client/main.cpp | 23 | SET (LIBEDIT_LIBS ${LIBEDIT_LIBRARIES}) |
57 | 24 | debug_client/debug_command.h | 24 | ENDIF (LIBEDIT_FOUND) |
58 | 25 | debug_client/debug_command.cpp | 25 | ENDIF (NOT WIN32) |
59 | 26 | debug_client/command_line_handler.h | 26 | |
60 | 27 | debug_client/command_line_handler.cpp | 27 | CHECK_INCLUDE_FILES ("editline/readline.h" ZORBA_HAVE_READLINE_H) |
61 | 28 | debug_client/lock_free_queue.h | 28 | CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/debugger/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/debugger/config.h) |
62 | 29 | debug_client/event_handler.h | 29 | MESSAGE(STATUS "configured ${CMAKE_CURRENT_SOURCE_DIR}/debugger/config.h.cmake --> ${CMAKE_CURRENT_BINARY_DIR}/debugger/config.h") |
63 | 30 | debug_client/event_handler.cpp | 30 | INCLUDE_DIRECTORIES (BEFORE ${CMAKE_CURRENT_BINARY_DIR}/debugger) |
64 | 31 | ${CMAKE_CURRENT_BINARY_DIR}/debug_client/event_handler_init.cpp | 31 | |
65 | 32 | SET (DEBUG_CLIENT_SRCS | ||
66 | 33 | debugger/main.cpp | ||
67 | 34 | debugger/command_prompt.cpp | ||
68 | 35 | debugger/command_line_handler.cpp | ||
69 | 36 | debugger/event_handler.cpp | ||
70 | 32 | ) | 37 | ) |
71 | 33 | 38 | ||
76 | 34 | CONFIGURE_FILE (debug_client/message-handler.xq message-handler.xq) | 39 | ZORBA_GENERATE_EXE ("xqdb" "${DEBUG_CLIENT_SRCS}" "${LIBEDIT_LIBS}" "xqdb" "bin") |
77 | 35 | 40 | ENDIF (ZORBA_WITH_DEBUGGER_CLIENT) | |
74 | 36 | ZORBA_GENERATE_EXE("debuggercmd" "${DEBUG_CLIENT_SRCS}" "" "debugger" "bin") | ||
75 | 37 | ENDIF(ZORBA_WITH_DEBUGGER_CLIENT) | ||
78 | 38 | 41 | ||
79 | 39 | SET(SRCS | 42 | SET(SRCS |
80 | 40 | zorbacmd.cpp | 43 | zorbacmd.cpp |
81 | 41 | 44 | ||
82 | === removed file 'bin/debug_client/debug_command.cpp' | |||
83 | --- bin/debug_client/debug_command.cpp 2011-07-01 01:53:24 +0000 | |||
84 | +++ bin/debug_client/debug_command.cpp 1970-01-01 00:00:00 +0000 | |||
85 | @@ -1,99 +0,0 @@ | |||
86 | 1 | /* | ||
87 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
88 | 3 | * | ||
89 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
90 | 5 | * you may not use this file except in compliance with the License. | ||
91 | 6 | * You may obtain a copy of the License at | ||
92 | 7 | * | ||
93 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
94 | 9 | * | ||
95 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
96 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
97 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
98 | 13 | * See the License for the specific language governing permissions and | ||
99 | 14 | * limitations under the License. | ||
100 | 15 | */ | ||
101 | 16 | #include <iostream> | ||
102 | 17 | #include "debug_client/debug_command.h" | ||
103 | 18 | |||
104 | 19 | namespace zorba { namespace debugclient { | ||
105 | 20 | |||
106 | 21 | |||
107 | 22 | void CommandLine::execute() | ||
108 | 23 | { | ||
109 | 24 | for (;;) { | ||
110 | 25 | std::cout << "zdb>> "; | ||
111 | 26 | std::string command; | ||
112 | 27 | std::getline(std::cin, command); | ||
113 | 28 | std::vector<std::string> args; | ||
114 | 29 | args << command; | ||
115 | 30 | std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.find(args[0]); | ||
116 | 31 | if (lIter == theCommands.end()) { | ||
117 | 32 | std::cout << args[0] << ": Command not found" << std::endl; | ||
118 | 33 | continue; | ||
119 | 34 | } | ||
120 | 35 | if (!lIter->second->execute(args)) | ||
121 | 36 | continue; | ||
122 | 37 | return; | ||
123 | 38 | } | ||
124 | 39 | } | ||
125 | 40 | |||
126 | 41 | |||
127 | 42 | CommandLine::~CommandLine() | ||
128 | 43 | { | ||
129 | 44 | for (std::map<std::string, UntypedCommand*>::iterator i = theCommands.begin(); | ||
130 | 45 | i != theCommands.end(); ++i) | ||
131 | 46 | { | ||
132 | 47 | delete i->second; | ||
133 | 48 | } | ||
134 | 49 | } | ||
135 | 50 | |||
136 | 51 | CommandLine& CommandLine::operator<<(UntypedCommand *aCommand) | ||
137 | 52 | { | ||
138 | 53 | theCommands.insert(std::make_pair(aCommand->get_name(), aCommand)); | ||
139 | 54 | return *this; | ||
140 | 55 | } | ||
141 | 56 | }} | ||
142 | 57 | |||
143 | 58 | namespace std { | ||
144 | 59 | vector<string>& operator<< (vector<string>& vec, const string& str) | ||
145 | 60 | { | ||
146 | 61 | string::size_type before = 0; | ||
147 | 62 | string::size_type pos = str.find(" ", 0); | ||
148 | 63 | while (pos != str.npos) { | ||
149 | 64 | std::string lSub = str.substr(before, pos - before); | ||
150 | 65 | if (lSub[0] == '"') { | ||
151 | 66 | std::string::size_type lBeforeCopy = before; | ||
152 | 67 | do { | ||
153 | 68 | lBeforeCopy = str.find("\"", lBeforeCopy + 1); | ||
154 | 69 | } while (pos != str.npos && str.size() > pos + 1 && str[pos + 1] == '\\'); | ||
155 | 70 | pos = lBeforeCopy; | ||
156 | 71 | lSub = str.substr(before + 1, pos - before - 1); | ||
157 | 72 | } | ||
158 | 73 | vec.push_back(lSub); | ||
159 | 74 | before = pos + 1; | ||
160 | 75 | pos = str.find(" ", before); | ||
161 | 76 | } | ||
162 | 77 | std::string lSub = str.substr(before); | ||
163 | 78 | if (lSub[0] == '"') { | ||
164 | 79 | pos = str.find("\"", before + 1); | ||
165 | 80 | lSub = str.substr(before + 1, pos - before - 1); | ||
166 | 81 | } | ||
167 | 82 | vec.push_back(lSub); | ||
168 | 83 | return vec; | ||
169 | 84 | } | ||
170 | 85 | |||
171 | 86 | set<string>& operator<< (set<string>& vec, const string& str) | ||
172 | 87 | { | ||
173 | 88 | string::size_type before = 0; | ||
174 | 89 | string::size_type pos = str.find(" ", 0); | ||
175 | 90 | while (pos != str.npos) { | ||
176 | 91 | vec.insert(str.substr(before, pos)); | ||
177 | 92 | before = pos + 1; | ||
178 | 93 | pos = str.find(" ", before); | ||
179 | 94 | } | ||
180 | 95 | vec.insert(str.substr(before)); | ||
181 | 96 | return vec; | ||
182 | 97 | } | ||
183 | 98 | |||
184 | 99 | } | ||
185 | 100 | 0 | ||
186 | === removed file 'bin/debug_client/event_handler_init.cpp.in' | |||
187 | --- bin/debug_client/event_handler_init.cpp.in 2011-07-01 01:53:24 +0000 | |||
188 | +++ bin/debug_client/event_handler_init.cpp.in 1970-01-01 00:00:00 +0000 | |||
189 | @@ -1,41 +0,0 @@ | |||
190 | 1 | /* | ||
191 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
192 | 3 | * | ||
193 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
194 | 5 | * you may not use this file except in compliance with the License. | ||
195 | 6 | * You may obtain a copy of the License at | ||
196 | 7 | * | ||
197 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
198 | 9 | * | ||
199 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
200 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
201 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
202 | 13 | * See the License for the specific language governing permissions and | ||
203 | 14 | * limitations under the License. | ||
204 | 15 | */ | ||
205 | 16 | #include <fstream> | ||
206 | 17 | #include "debug_client/event_handler.h" | ||
207 | 18 | |||
208 | 19 | namespace zorba { namespace debugclient { | ||
209 | 20 | |||
210 | 21 | std::istream* EventHandler::getCurrentDirectory() { | ||
211 | 22 | const char* build_dir = "@CMAKE_BINARY_DIR@/bin/message-handler.xq"; | ||
212 | 23 | const char* install_dir = | ||
213 | 24 | #ifndef WIN32 | ||
214 | 25 | "@CMAKE_INSTALL_PREFIX@/bin/"; | ||
215 | 26 | #else | ||
216 | 27 | "C:/Program Files/Zorba XQuery Processor @ZORBA_MAJOR_NUMBER@.@ZORBA_MINOR_NUMBER@.@ZORBA_PATCH_NUMBER@/bin/"; | ||
217 | 28 | #endif | ||
218 | 29 | std::auto_ptr<std::ifstream> stream(new std::ifstream(build_dir)); | ||
219 | 30 | if (stream->good()) { | ||
220 | 31 | return stream.release(); | ||
221 | 32 | } | ||
222 | 33 | stream.reset(new std::ifstream(install_dir)); | ||
223 | 34 | if (stream->good()) { | ||
224 | 35 | return stream.release(); | ||
225 | 36 | } | ||
226 | 37 | return 0; | ||
227 | 38 | } | ||
228 | 39 | |||
229 | 40 | }} // end of namespace zorba::debugclient | ||
230 | 41 | |||
231 | 42 | 0 | ||
232 | === removed file 'bin/debug_client/lock_free_queue.cpp' | |||
233 | --- bin/debug_client/lock_free_queue.cpp 2011-07-01 01:53:24 +0000 | |||
234 | +++ bin/debug_client/lock_free_queue.cpp 1970-01-01 00:00:00 +0000 | |||
235 | @@ -1,16 +0,0 @@ | |||
236 | 1 | /* | ||
237 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
238 | 3 | * | ||
239 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
240 | 5 | * you may not use this file except in compliance with the License. | ||
241 | 6 | * You may obtain a copy of the License at | ||
242 | 7 | * | ||
243 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
244 | 9 | * | ||
245 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
246 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
247 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
248 | 13 | * See the License for the specific language governing permissions and | ||
249 | 14 | * limitations under the License. | ||
250 | 15 | */ | ||
251 | 16 | #include "lock_free_queue.h" | ||
252 | 17 | 0 | ||
253 | === removed file 'bin/debug_client/message-handler.xq' | |||
254 | --- bin/debug_client/message-handler.xq 2011-08-26 23:36:24 +0000 | |||
255 | +++ bin/debug_client/message-handler.xq 1970-01-01 00:00:00 +0000 | |||
256 | @@ -1,165 +0,0 @@ | |||
257 | 1 | (: | ||
258 | 2 | : Copyright 2006-2009 The FLWOR Foundation. | ||
259 | 3 | : | ||
260 | 4 | : Licensed under the Apache License, Version 2.0 (the "License"); | ||
261 | 5 | : you may not use this file except in compliance with the License. | ||
262 | 6 | : You may obtain a copy of the License at | ||
263 | 7 | : | ||
264 | 8 | : http://www.apache.org/licenses/LICENSE-2.0 | ||
265 | 9 | : | ||
266 | 10 | : Unless required by applicable law or agreed to in writing, software | ||
267 | 11 | : distributed under the License is distributed on an "AS IS" BASIS, | ||
268 | 12 | : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
269 | 13 | : See the License for the specific language governing permissions and | ||
270 | 14 | : limitations under the License. | ||
271 | 15 | :) | ||
272 | 16 | |||
273 | 17 | import module namespace refl = 'http://www.zorba-xquery.com/modules/reflection'; | ||
274 | 18 | import module namespace sctx = "http://www.zorba-xquery.com/modules/introspection/sctx"; | ||
275 | 19 | import module namespace base64 = "http://www.zorba-xquery.com/modules/converters/base64"; | ||
276 | 20 | |||
277 | 21 | |||
278 | 22 | declare variable $local:localns as xs:string := 'http://www.w3.org/2005/xquery-local-functions'; | ||
279 | 23 | |||
280 | 24 | |||
281 | 25 | declare variable $local:endl as xs:string := ' | ||
282 | 26 | '; | ||
283 | 27 | |||
284 | 28 | declare function local:has-to-stop($resp as element()) | ||
285 | 29 | { | ||
286 | 30 | fn:not(($resp/@command/data(.) eq "stop" and $resp/@reason/data(.) eq "ok") | ||
287 | 31 | or ($resp/@status/data(.) eq "stopped") | ||
288 | 32 | or ($resp/@status/data(.) eq "stopping")) | ||
289 | 33 | }; | ||
290 | 34 | |||
291 | 35 | declare function local:status($resp as element()) | ||
292 | 36 | { | ||
293 | 37 | fn:concat( | ||
294 | 38 | "Status: ", $resp/@status/data(.), $local:endl, | ||
295 | 39 | "Reason: ", $resp/@reason/data(.), $local:endl, | ||
296 | 40 | let $msg := $resp/text() | ||
297 | 41 | return | ||
298 | 42 | if (fn:empty($msg) or $msg eq "") then | ||
299 | 43 | "" | ||
300 | 44 | else | ||
301 | 45 | fn:concat($msg, $local:endl) | ||
302 | 46 | ) | ||
303 | 47 | }; | ||
304 | 48 | |||
305 | 49 | |||
306 | 50 | declare function local:run($resp as element()) { | ||
307 | 51 | if ($resp/@status/data(.) eq "starting") then | ||
308 | 52 | "Starting query" | ||
309 | 53 | else | ||
310 | 54 | local:status($resp) | ||
311 | 55 | }; | ||
312 | 56 | |||
313 | 57 | declare function local:stop($resp as element()) | ||
314 | 58 | { | ||
315 | 59 | local:status($resp) | ||
316 | 60 | }; | ||
317 | 61 | |||
318 | 62 | declare function local:breakpoint_set($resp as element()) | ||
319 | 63 | { | ||
320 | 64 | if ($resp/error) then | ||
321 | 65 | fn:concat("Error when setting a breakpoint: ", if ($resp/error/message) then $resp/error/message/text() else concat(" errcode: ", data($resp/error/@code))) | ||
322 | 66 | else | ||
323 | 67 | fn:concat("set breakpoint with id ", data($resp/@id), " and state ", data($resp/@state)) | ||
324 | 68 | }; | ||
325 | 69 | |||
326 | 70 | declare function local:breakpoint_list($resp as element()) | ||
327 | 71 | { | ||
328 | 72 | string-join( | ||
329 | 73 | for $b in $resp/breakpoint | ||
330 | 74 | return concat("Breakpoint ", data($b/@id), " at ", data($b/@filename), ":", data($b/@lineno), " ", data($b/@state)), | ||
331 | 75 | $local:endl | ||
332 | 76 | ) | ||
333 | 77 | }; | ||
334 | 78 | |||
335 | 79 | declare function local:breakpoint_remove($resp as element()) | ||
336 | 80 | { | ||
337 | 81 | "Breakpoint removed" | ||
338 | 82 | }; | ||
339 | 83 | |||
340 | 84 | declare function local:stack_depth($resp as element()) | ||
341 | 85 | { | ||
342 | 86 | concat("Depth: ", data($resp/@depth)) | ||
343 | 87 | }; | ||
344 | 88 | |||
345 | 89 | declare function local:stack_get($resp as element()) | ||
346 | 90 | { | ||
347 | 91 | string-join( | ||
348 | 92 | for $s in $resp/stack | ||
349 | 93 | return concat("Level ", data($s/@level), " at ", data($s/@filename), ":", data($s/@lineno)), | ||
350 | 94 | $local:endl | ||
351 | 95 | ) | ||
352 | 96 | }; | ||
353 | 97 | |||
354 | 98 | |||
355 | 99 | declare function local:context_names($resp as element()) | ||
356 | 100 | { | ||
357 | 101 | string-join( | ||
358 | 102 | for $c in $resp/context | ||
359 | 103 | return concat("Context: ", data($c/@name), " id: ", data($c/@id)), | ||
360 | 104 | $local:endl | ||
361 | 105 | ) | ||
362 | 106 | }; | ||
363 | 107 | |||
364 | 108 | declare function local:context_get($resp as element()) | ||
365 | 109 | { | ||
366 | 110 | string-join( | ||
367 | 111 | for $p in $resp/property | ||
368 | 112 | return concat(data($p/@fullname), ": [", data($p/@type), "]", | ||
369 | 113 | if ($p/text() ne "") then concat(": ", base64:decode($p/text())) else ""), | ||
370 | 114 | $local:endl | ||
371 | 115 | ) | ||
372 | 116 | }; | ||
373 | 117 | |||
374 | 118 | declare function local:eval($resp as element()) | ||
375 | 119 | { | ||
376 | 120 | if (data($resp/@success) eq "1") then | ||
377 | 121 | local:context_get($resp) | ||
378 | 122 | else | ||
379 | 123 | concat("Eval failed", ":", $resp/error/message/text()) | ||
380 | 124 | }; | ||
381 | 125 | |||
382 | 126 | declare function local:process-response($resp as element()) | ||
383 | 127 | { | ||
384 | 128 | if (data($resp/@command) eq "") then | ||
385 | 129 | (fn:true(), $resp/@transaction_id/data(.), local:status($resp)) | ||
386 | 130 | else | ||
387 | 131 | let $fun-cont-name := fn:QName($local:localns, concat("local:", $resp/@command/data(.), "-cont")) | ||
388 | 132 | let $fun-msg-name := fn:QName($local:localns, concat("local:", $resp/@command/data(.))) | ||
389 | 133 | return ( | ||
390 | 134 | if (sctx:function-arguments-count($fun-cont-name) = 1) then | ||
391 | 135 | refl:invoke($fun-cont-name, $resp) | ||
392 | 136 | else | ||
393 | 137 | local:has-to-stop($resp), | ||
394 | 138 | $resp/@transaction_id/data(.), | ||
395 | 139 | if (sctx:function-arguments-count($fun-msg-name) = 1) then | ||
396 | 140 | refl:invoke($fun-msg-name, $resp) | ||
397 | 141 | else | ||
398 | 142 | "Recieved a message - command not implemented" | ||
399 | 143 | ) | ||
400 | 144 | }; | ||
401 | 145 | |||
402 | 146 | declare function local:process-init($init as element()) | ||
403 | 147 | { | ||
404 | 148 | fn:true(), | ||
405 | 149 | 0, | ||
406 | 150 | fn:concat(fn:string-join( | ||
407 | 151 | ('Established connection with', $init/@language/data(.), 'client', $init/@appid/data(.)), ' '), ' | ||
408 | 152 | ') | ||
409 | 153 | }; | ||
410 | 154 | |||
411 | 155 | declare function local:main($response as element()) { | ||
412 | 156 | let $process-fun as xs:QName := fn:QName($local:localns, concat("local:process-", node-name($response))) | ||
413 | 157 | return | ||
414 | 158 | if (sctx:function-arguments-count($process-fun) = 1) then | ||
415 | 159 | refl:invoke($process-fun, $response) | ||
416 | 160 | else ( | ||
417 | 161 | true(), | ||
418 | 162 | ($response/@transaction_id, 0)[1]/data(.), | ||
419 | 163 | "ERROR: Recieved unknown node from client" | ||
420 | 164 | ) | ||
421 | 165 | }; | ||
422 | 166 | 0 | ||
423 | === renamed directory 'bin/debug_client' => 'bin/debugger' | |||
424 | === renamed file 'bin/debug_client/debug_command.h' => 'bin/debugger/command.h' | |||
425 | --- bin/debug_client/debug_command.h 2011-07-04 08:05:46 +0000 | |||
426 | +++ bin/debugger/command.h 2011-12-20 18:15:30 +0000 | |||
427 | @@ -14,7 +14,9 @@ | |||
428 | 14 | * limitations under the License. | 14 | * limitations under the License. |
429 | 15 | */ | 15 | */ |
430 | 16 | #pragma once | 16 | #pragma once |
432 | 17 | #include <zorba/config.h> | 17 | #ifndef ZORBA_DEBUGGER_COMMAND_H |
433 | 18 | #define ZORBA_DEBUGGER_COMMAND_H | ||
434 | 19 | |||
435 | 18 | #include <string> | 20 | #include <string> |
436 | 19 | #include <vector> | 21 | #include <vector> |
437 | 20 | #include <iostream> | 22 | #include <iostream> |
438 | @@ -23,151 +25,18 @@ | |||
439 | 23 | #include <sstream> | 25 | #include <sstream> |
440 | 24 | #include <memory> | 26 | #include <memory> |
441 | 25 | #include <typeinfo> | 27 | #include <typeinfo> |
445 | 26 | #include "debug_client/tuple.h" | 28 | |
446 | 27 | 29 | #include <zorba/config.h> | |
447 | 28 | namespace zorba { namespace debugclient { | 30 | |
448 | 31 | #include "command_arg.h" | ||
449 | 32 | #include "tuple.h" | ||
450 | 33 | |||
451 | 34 | |||
452 | 35 | namespace zorba { namespace debugger { | ||
453 | 29 | 36 | ||
454 | 30 | class DebugClientParseException : public std::exception { | 37 | class DebugClientParseException : public std::exception { |
455 | 31 | }; | 38 | }; |
456 | 32 | 39 | ||
457 | 33 | template<typename Tuple> | ||
458 | 34 | class CommandArg; | ||
459 | 35 | |||
460 | 36 | template<typename Tuple> | ||
461 | 37 | class CommandArgInstance { | ||
462 | 38 | public: | ||
463 | 39 | virtual int get_index() const = 0; | ||
464 | 40 | virtual const CommandArg<Tuple>* get_arg() const = 0; | ||
465 | 41 | virtual void insertValue(Tuple& t) = 0; | ||
466 | 42 | virtual bool isSet(Tuple& t) const = 0; | ||
467 | 43 | }; | ||
468 | 44 | |||
469 | 45 | template<typename T, int Idx, typename Tuple> | ||
470 | 46 | class TypedCommandArgInstance : public CommandArgInstance<Tuple> | ||
471 | 47 | { | ||
472 | 48 | public: | ||
473 | 49 | TypedCommandArgInstance(T aValue, const CommandArg<Tuple>* aArg) | ||
474 | 50 | : theValue(aValue), theArg(aArg) {} | ||
475 | 51 | virtual int get_index() const { return Idx; } | ||
476 | 52 | virtual const CommandArg<Tuple>* get_arg() const { return theArg; } | ||
477 | 53 | virtual void insertValue(Tuple& t) | ||
478 | 54 | { | ||
479 | 55 | ZORBA_TR1_NS::get<Idx>(t).first = true; | ||
480 | 56 | ZORBA_TR1_NS::get<Idx>(t).second = theValue; | ||
481 | 57 | } | ||
482 | 58 | virtual bool isSet(Tuple& t) const | ||
483 | 59 | { | ||
484 | 60 | return ZORBA_TR1_NS::get<Idx>(t).first; | ||
485 | 61 | } | ||
486 | 62 | private: | ||
487 | 63 | T theValue; | ||
488 | 64 | const CommandArg<Tuple>* theArg; | ||
489 | 65 | }; | ||
490 | 66 | |||
491 | 67 | template<typename Tuple> | ||
492 | 68 | class CommandArgType { | ||
493 | 69 | public: | ||
494 | 70 | virtual CommandArgInstance<Tuple>* parse(const std::string& str, | ||
495 | 71 | const CommandArg<Tuple>* arg) = 0; | ||
496 | 72 | virtual bool isVoid() const = 0; | ||
497 | 73 | virtual bool isSet(Tuple& t) const = 0; | ||
498 | 74 | virtual ~CommandArgType() {} | ||
499 | 75 | }; | ||
500 | 76 | |||
501 | 77 | template<typename T, int Idx, typename Tuple> | ||
502 | 78 | class TypedCommandArgType : public CommandArgType<Tuple> { | ||
503 | 79 | public: | ||
504 | 80 | typedef T Type; | ||
505 | 81 | public: // implementation | ||
506 | 82 | TypedCommandArgType(bool aIsVoid) : theIsVoid(aIsVoid) {} | ||
507 | 83 | TypedCommandArgType(const T& aValue, | ||
508 | 84 | bool aIsVoid) | ||
509 | 85 | : theDefault(aValue), theIsVoid(aIsVoid) {} | ||
510 | 86 | virtual CommandArgInstance<Tuple>* parse(const std::string& str, | ||
511 | 87 | const CommandArg<Tuple>* arg) | ||
512 | 88 | { | ||
513 | 89 | T aValue; | ||
514 | 90 | std::stringstream stream(str); | ||
515 | 91 | stream >> aValue; | ||
516 | 92 | if (stream.fail()) { | ||
517 | 93 | std::cerr << "Could not parse argument of type " | ||
518 | 94 | << typeid(T).name() | ||
519 | 95 | << std::endl; | ||
520 | 96 | return 0; | ||
521 | 97 | } | ||
522 | 98 | return new TypedCommandArgInstance<T, Idx, Tuple>(aValue, arg); | ||
523 | 99 | } | ||
524 | 100 | virtual bool isVoid() const { return theIsVoid; } | ||
525 | 101 | virtual bool isSet(Tuple& t) const | ||
526 | 102 | { | ||
527 | 103 | return ZORBA_TR1_NS::get<Idx>(t).first; | ||
528 | 104 | } | ||
529 | 105 | private: | ||
530 | 106 | TypedCommandArgType<T, Idx, Tuple>() {} | ||
531 | 107 | T theDefault; | ||
532 | 108 | bool theIsVoid; | ||
533 | 109 | }; | ||
534 | 110 | |||
535 | 111 | template<typename Tuple> | ||
536 | 112 | class CommandArg { | ||
537 | 113 | public: | ||
538 | 114 | CommandArg(unsigned aId, | ||
539 | 115 | CommandArgType<Tuple>* aType, | ||
540 | 116 | const std::set<std::string>& aFlags, | ||
541 | 117 | const std::string& aDescription, | ||
542 | 118 | bool aIsRequired) | ||
543 | 119 | : theId(aId), | ||
544 | 120 | theType(aType), | ||
545 | 121 | theFlags(aFlags), | ||
546 | 122 | theDescription(aDescription), | ||
547 | 123 | theIsRequired(aIsRequired) | ||
548 | 124 | { | ||
549 | 125 | } | ||
550 | 126 | ~CommandArg() { delete theType; } | ||
551 | 127 | unsigned get_id() const { return theId; } | ||
552 | 128 | bool canHandle(const std::string& arg) const | ||
553 | 129 | { | ||
554 | 130 | if (theFlags.find(arg) != theFlags.end()) { | ||
555 | 131 | return true; | ||
556 | 132 | } | ||
557 | 133 | return false; | ||
558 | 134 | } | ||
559 | 135 | CommandArgInstance<Tuple>* parse(const std::string& str) const | ||
560 | 136 | { | ||
561 | 137 | return theType->parse(str, this); | ||
562 | 138 | } | ||
563 | 139 | bool isVoid() const { | ||
564 | 140 | return theType->isVoid(); | ||
565 | 141 | } | ||
566 | 142 | bool isRequired() const { return theIsRequired; } | ||
567 | 143 | std::string get_name() const { | ||
568 | 144 | return *(theFlags.begin()); | ||
569 | 145 | } | ||
570 | 146 | bool isSet(Tuple& t) const | ||
571 | 147 | { | ||
572 | 148 | return theType->isSet(t); | ||
573 | 149 | } | ||
574 | 150 | private: | ||
575 | 151 | unsigned theId; | ||
576 | 152 | CommandArgType<Tuple>* theType; | ||
577 | 153 | std::set<std::string> theFlags; | ||
578 | 154 | std::string theDescription; | ||
579 | 155 | bool theIsRequired; | ||
580 | 156 | }; | ||
581 | 157 | }} // end namespace zorba | ||
582 | 158 | |||
583 | 159 | namespace std { | ||
584 | 160 | |||
585 | 161 | /** | ||
586 | 162 | * This is a helper split function | ||
587 | 163 | */ | ||
588 | 164 | vector<string>& operator<< (vector<string>& vec, const string& str); | ||
589 | 165 | |||
590 | 166 | set<string>& operator<< (set<string>& vec, const string& str); | ||
591 | 167 | } //end namespace std | ||
592 | 168 | |||
593 | 169 | namespace zorba { namespace debugclient { | ||
594 | 170 | |||
595 | 171 | template<typename Func, typename Tuple, int CommandIdx> | 40 | template<typename Func, typename Tuple, int CommandIdx> |
596 | 172 | class CommandInstance | 41 | class CommandInstance |
597 | 173 | { | 42 | { |
598 | @@ -188,8 +57,10 @@ | |||
599 | 188 | 57 | ||
600 | 189 | class UntypedCommand { | 58 | class UntypedCommand { |
601 | 190 | public: | 59 | public: |
604 | 191 | virtual std::string get_name() const = 0; | 60 | virtual std::string getName() const = 0; |
605 | 192 | virtual std::string get_description() const = 0; | 61 | virtual std::set<std::string> getAliases() const = 0; |
606 | 62 | virtual std::string getDescription() const = 0; | ||
607 | 63 | virtual void printHelp() const = 0; | ||
608 | 193 | virtual bool execute(const std::vector<std::string>& args) = 0; | 64 | virtual bool execute(const std::vector<std::string>& args) = 0; |
609 | 194 | }; | 65 | }; |
610 | 195 | 66 | ||
611 | @@ -197,77 +68,141 @@ | |||
612 | 197 | class Command : public UntypedCommand { | 68 | class Command : public UntypedCommand { |
613 | 198 | public: | 69 | public: |
614 | 199 | Command(const std::string& aName, Func& aFunction, const std::string& aDescription) | 70 | Command(const std::string& aName, Func& aFunction, const std::string& aDescription) |
616 | 200 | : theName(aName), theFunction(aFunction), theDescription(aDescription) {} | 71 | : theName(aName), theFunction(aFunction), theDescription(aDescription) |
617 | 72 | {} | ||
618 | 73 | |||
619 | 74 | Command(const std::string& aName, const std::set<std::string> aAliases, Func& aFunction, const std::string& aDescription) | ||
620 | 75 | : theName(aName), theAliases(aAliases), theFunction(aFunction), theDescription(aDescription) | ||
621 | 76 | {} | ||
622 | 77 | |||
623 | 201 | ~Command(); | 78 | ~Command(); |
624 | 79 | |||
625 | 202 | public: | 80 | public: |
633 | 203 | Command& operator() (unsigned aId, | 81 | |
634 | 204 | const std::string& aFlags, | 82 | void |
635 | 205 | CommandArgType<Tuple>* aType, | 83 | addArgument( |
636 | 206 | const std::string& aDescription = "", | 84 | unsigned aId, |
637 | 207 | bool isRequired = false); | 85 | const std::string& aFlags, |
638 | 208 | virtual std::string get_name() const { return theName; } | 86 | CommandArgType<Tuple>* aType, |
639 | 209 | virtual std::string get_description() const { return theDescription; } | 87 | const std::string& aDescription = "", |
640 | 88 | bool isRequired = false); | ||
641 | 89 | |||
642 | 90 | static void | ||
643 | 91 | splitNames( | ||
644 | 92 | const std::string& names, | ||
645 | 93 | std::set<std::string>& set); | ||
646 | 94 | |||
647 | 95 | virtual std::string | ||
648 | 96 | getName() const | ||
649 | 97 | { | ||
650 | 98 | return theName; | ||
651 | 99 | } | ||
652 | 100 | |||
653 | 101 | virtual std::set<std::string> getAliases() const | ||
654 | 102 | { | ||
655 | 103 | return theAliases; | ||
656 | 104 | } | ||
657 | 105 | |||
658 | 106 | virtual std::string | ||
659 | 107 | getDescription() const | ||
660 | 108 | { | ||
661 | 109 | return theDescription; | ||
662 | 110 | } | ||
663 | 111 | |||
664 | 112 | virtual void | ||
665 | 113 | printHelp() const; | ||
666 | 114 | |||
667 | 210 | virtual bool execute(const std::vector<std::string>& args) | 115 | virtual bool execute(const std::vector<std::string>& args) |
668 | 211 | { | 116 | { |
669 | 212 | CommandInstance<Func, Tuple, CommandIdx> instance(theFunction, theTuple); | 117 | CommandInstance<Func, Tuple, CommandIdx> instance(theFunction, theTuple); |
671 | 213 | if (instance.parseArguments(args, theArgs)) | 118 | if (instance.parseArguments(args, theArgs)) { |
672 | 214 | instance.execute(); | 119 | instance.execute(); |
676 | 215 | else | 120 | return true; |
677 | 216 | return false; | 121 | } |
678 | 217 | return true; | 122 | return false; |
679 | 218 | } | 123 | } |
680 | 219 | private: | 124 | private: |
681 | 220 | std::string theName; | 125 | std::string theName; |
682 | 126 | std::set<std::string> theAliases; | ||
683 | 221 | Func& theFunction; | 127 | Func& theFunction; |
684 | 222 | Tuple theTuple; | 128 | Tuple theTuple; |
685 | 223 | std::string theDescription; | 129 | std::string theDescription; |
733 | 224 | std::map<std::string, CommandArg<Tuple>* > theArgs; | 130 | std::map<std::string, CommandArg<Tuple>*> theArgs; |
734 | 225 | }; | 131 | }; |
735 | 226 | 132 | ||
736 | 227 | class CommandLine { | 133 | /*****************************************************************************/ |
737 | 228 | public: | 134 | /*****************************************************************************/ |
738 | 229 | ~CommandLine(); | 135 | |
739 | 230 | public: | 136 | template<typename Func, typename Tuple, int CommandIdx> |
740 | 231 | void execute(); | 137 | Command<Func, Tuple, CommandIdx>::~Command() |
741 | 232 | CommandLine& operator<< (UntypedCommand* aCommand); | 138 | { |
742 | 233 | private: | 139 | typedef std::map<std::string, CommandArg<Tuple>*> ArgType; |
743 | 234 | std::map<std::string, UntypedCommand*> theCommands; | 140 | for (typename ArgType::iterator i = theArgs.begin(); i != theArgs.end(); ++i) { |
744 | 235 | }; | 141 | delete i->second; |
745 | 236 | 142 | } | |
746 | 237 | template<typename Func, typename Tuple, int CommandIdx> | 143 | } |
747 | 238 | Command<Func, Tuple, CommandIdx>::~Command() | 144 | |
748 | 239 | { | 145 | template<typename Func, typename Tuple, int CommandIdx> |
749 | 240 | typedef std::map<std::string, CommandArg<Tuple>* > ArgType; | 146 | void |
750 | 241 | for (typename ArgType::iterator i = theArgs.begin(); i != theArgs.end(); ++i) { | 147 | Command<Func, Tuple, CommandIdx>::printHelp() const |
751 | 242 | delete i->second; | 148 | { |
752 | 243 | } | 149 | std::cout << "Purpose: " << getDescription() << std::endl; |
753 | 244 | } | 150 | |
754 | 245 | 151 | typename std::map<std::string, CommandArg<Tuple>*>::const_iterator lIter = theArgs.begin(); | |
755 | 246 | 152 | if (lIter == theArgs.end()) { | |
756 | 247 | template<typename Func, typename Tuple, int CommandIdx> | 153 | std::cout << "This command has no arguments." << std::endl; |
757 | 248 | Command<Func, Tuple, CommandIdx>& | 154 | std::cout << std::endl; |
758 | 249 | Command<Func, Tuple, CommandIdx>::operator() (unsigned aId, | 155 | return; |
759 | 250 | const std::string& aFlags, | 156 | } |
760 | 251 | CommandArgType<Tuple>* aType, | 157 | |
761 | 252 | const std::string& aDescription, | 158 | std::cout << "Arguments:" << std::endl << std::endl; |
762 | 253 | bool isRequired) | 159 | for (; lIter != theArgs.end(); ++lIter) { |
763 | 254 | { | 160 | std::cout << " " << lIter->first << "\t" << lIter->second->getDescription() << std::endl; |
764 | 255 | std::set<std::string> args; | 161 | } |
765 | 256 | args << aFlags; | 162 | std::cout << std::endl; |
766 | 257 | for (std::set<std::string>::iterator i = args.begin(); i != args.end(); ++i) { | 163 | } |
767 | 258 | std::string toAdd = (i->size() == 1) ? "-" + *i : "--" + *i; | 164 | |
768 | 259 | theArgs.insert(std::make_pair(toAdd, | 165 | template<typename Func, typename Tuple, int CommandIdx> |
769 | 260 | new CommandArg<Tuple>(aId, | 166 | void |
770 | 261 | aType, | 167 | Command<Func, Tuple, CommandIdx>::splitNames(const std::string& aNames, std::set<std::string>& aSet) |
771 | 262 | args, | 168 | { |
772 | 263 | aDescription, | 169 | std::string::size_type before = 0; |
773 | 264 | isRequired) | 170 | std::string::size_type pos = aNames.find(" ", 0); |
774 | 265 | ) | 171 | while (pos != aNames.npos) { |
775 | 266 | ); | 172 | std::string lName = aNames.substr(before, pos); |
776 | 267 | } | 173 | if (lName != "") { |
777 | 268 | return *this; | 174 | aSet.insert(lName); |
778 | 269 | } | 175 | } |
779 | 270 | 176 | before = pos + 1; | |
780 | 177 | pos = aNames.find(" ", before); | ||
781 | 178 | } | ||
782 | 179 | std::string lName = aNames.substr(before); | ||
783 | 180 | if (lName != "") { | ||
784 | 181 | aSet.insert(lName); | ||
785 | 182 | } | ||
786 | 183 | } | ||
787 | 184 | |||
788 | 185 | template<typename Func, typename Tuple, int CommandIdx> | ||
789 | 186 | void | ||
790 | 187 | Command<Func, Tuple, CommandIdx>::addArgument( | ||
791 | 188 | unsigned aId, | ||
792 | 189 | const std::string& aFlags, | ||
793 | 190 | CommandArgType<Tuple>* aType, | ||
794 | 191 | const std::string& aDescription, | ||
795 | 192 | bool isRequired) | ||
796 | 193 | { | ||
797 | 194 | std::set<std::string> lNames; | ||
798 | 195 | splitNames(aFlags, lNames); | ||
799 | 196 | |||
800 | 197 | for (std::set<std::string>::iterator i = lNames.begin(); i != lNames.end(); ++i) { | ||
801 | 198 | std::string toAdd = (i->size() == 1) ? "-" + *i : "--" + *i; | ||
802 | 199 | CommandArg<Tuple>* lArg = new CommandArg<Tuple>(aId, aType, lNames, aDescription, isRequired); | ||
803 | 200 | theArgs.insert(std::make_pair(toAdd, lArg)); | ||
804 | 201 | } | ||
805 | 202 | } | ||
806 | 203 | |||
807 | 204 | /*****************************************************************************/ | ||
808 | 205 | |||
809 | 271 | template<typename Tuple, typename T, int Idx> | 206 | template<typename Tuple, typename T, int Idx> |
810 | 272 | CommandArgType<Tuple>* createArgType(Tuple t) | 207 | CommandArgType<Tuple>* createArgType(Tuple t) |
811 | 273 | { | 208 | { |
812 | @@ -290,6 +225,16 @@ | |||
813 | 290 | return new Command<Func, Tuple, CommandIdx>(aName, aFunction, aDescription); | 225 | return new Command<Func, Tuple, CommandIdx>(aName, aFunction, aDescription); |
814 | 291 | } | 226 | } |
815 | 292 | 227 | ||
816 | 228 | template<int CommandIdx, typename Tuple, typename Func> | ||
817 | 229 | Command<Func, Tuple, CommandIdx>* createCommand(Tuple t, | ||
818 | 230 | const std::string& aName, | ||
819 | 231 | const std::set<std::string>& aAliases, | ||
820 | 232 | Func& aFunction, | ||
821 | 233 | const std::string& aDescription) | ||
822 | 234 | { | ||
823 | 235 | return new Command<Func, Tuple, CommandIdx>(aName, aAliases, aFunction, aDescription); | ||
824 | 236 | } | ||
825 | 237 | |||
826 | 293 | template<typename Func, typename Tuple, int CommandIdx> | 238 | template<typename Func, typename Tuple, int CommandIdx> |
827 | 294 | bool CommandInstance<Func, Tuple, CommandIdx>:: | 239 | bool CommandInstance<Func, Tuple, CommandIdx>:: |
828 | 295 | parseArguments(const std::vector<std::string>& args, | 240 | parseArguments(const std::vector<std::string>& args, |
829 | @@ -301,29 +246,34 @@ | |||
830 | 301 | for (ArgType::size_type i = 1; i < size; ++i) { | 246 | for (ArgType::size_type i = 1; i < size; ++i) { |
831 | 302 | typename CArgType::const_iterator pos = aCommandArgs.find(args[i]); | 247 | typename CArgType::const_iterator pos = aCommandArgs.find(args[i]); |
832 | 303 | if (pos == aCommandArgs.end()) { | 248 | if (pos == aCommandArgs.end()) { |
834 | 304 | std::cerr << "Error: Unknown Argument " << args[i] << std::endl; | 249 | std::cerr << "Error: Unknown option " << args[i] << std::endl; |
835 | 305 | parseError = true; | 250 | parseError = true; |
836 | 306 | return false; | 251 | return false; |
837 | 307 | } | 252 | } |
838 | 308 | const CommandArg<Tuple>& arg = *(pos->second); | 253 | const CommandArg<Tuple>& arg = *(pos->second); |
839 | 309 | if (!arg.isVoid() && args[++i][0] == '-') { | ||
840 | 310 | std::cerr << "Did not expect parameter for option " << args[i] << std::endl; | ||
841 | 311 | return false; | ||
842 | 312 | } | ||
843 | 313 | std::auto_ptr<CommandArgInstance<Tuple> > instance; | 254 | std::auto_ptr<CommandArgInstance<Tuple> > instance; |
844 | 314 | if (arg.isVoid()) { | 255 | if (arg.isVoid()) { |
845 | 315 | instance.reset(arg.parse("1")); | 256 | instance.reset(arg.parse("1")); |
846 | 316 | } else { | 257 | } else { |
847 | 258 | ++i; | ||
848 | 259 | if (i >= size) { | ||
849 | 260 | std::cerr << "Error: Missing value for argument " << args[i - 1] << std::endl; | ||
850 | 261 | parseError = true; | ||
851 | 262 | allSet = false; | ||
852 | 263 | return false; | ||
853 | 264 | } | ||
854 | 317 | instance.reset(arg.parse(args[i])); | 265 | instance.reset(arg.parse(args[i])); |
855 | 318 | } | 266 | } |
857 | 319 | instance->insertValue(theTuple); | 267 | if (instance.get()) { |
858 | 268 | instance->insertValue(theTuple); | ||
859 | 269 | } | ||
860 | 320 | } | 270 | } |
861 | 321 | bool allSet = true; | 271 | bool allSet = true; |
862 | 322 | for (typename CArgType::const_iterator i = aCommandArgs.begin(); | 272 | for (typename CArgType::const_iterator i = aCommandArgs.begin(); |
863 | 323 | i != aCommandArgs.end(); ++i) | 273 | i != aCommandArgs.end(); ++i) |
864 | 324 | { | 274 | { |
865 | 325 | if (i->second->isRequired() && !i->second->isSet(theTuple)) { | 275 | if (i->second->isRequired() && !i->second->isSet(theTuple)) { |
867 | 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; |
868 | 327 | allSet = false; | 277 | allSet = false; |
869 | 328 | } | 278 | } |
870 | 329 | } | 279 | } |
871 | @@ -336,4 +286,7 @@ | |||
872 | 336 | theFunction.template handle<CommandIdx>(this->theTuple); | 286 | theFunction.template handle<CommandIdx>(this->theTuple); |
873 | 337 | } | 287 | } |
874 | 338 | 288 | ||
876 | 339 | }} // end of namespace zorba::debugclient | 289 | } // namespace zorba |
877 | 290 | } // namespace debugger | ||
878 | 291 | |||
879 | 292 | #endif // ZORBA_DEBUGGER_COMMAND_H | ||
880 | 340 | 293 | ||
881 | === added file 'bin/debugger/command_arg.h' | |||
882 | --- bin/debugger/command_arg.h 1970-01-01 00:00:00 +0000 | |||
883 | +++ bin/debugger/command_arg.h 2011-12-20 18:15:30 +0000 | |||
884 | @@ -0,0 +1,237 @@ | |||
885 | 1 | /* | ||
886 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
887 | 3 | * | ||
888 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
889 | 5 | * you may not use this file except in compliance with the License. | ||
890 | 6 | * You may obtain a copy of the License at | ||
891 | 7 | * | ||
892 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
893 | 9 | * | ||
894 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
895 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
896 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
897 | 13 | * See the License for the specific language governing permissions and | ||
898 | 14 | * limitations under the License. | ||
899 | 15 | */ | ||
900 | 16 | #pragma once | ||
901 | 17 | #ifndef ZORBA_DEBUGGER_COMMAND_ARG_H | ||
902 | 18 | #define ZORBA_DEBUGGER_COMMAND_ARG_H | ||
903 | 19 | |||
904 | 20 | #include <string> | ||
905 | 21 | #include <iostream> | ||
906 | 22 | #include <set> | ||
907 | 23 | #include <sstream> | ||
908 | 24 | |||
909 | 25 | #include "tuple.h" | ||
910 | 26 | |||
911 | 27 | |||
912 | 28 | namespace zorba { namespace debugger { | ||
913 | 29 | |||
914 | 30 | template<typename Tuple> | ||
915 | 31 | class CommandArg; | ||
916 | 32 | |||
917 | 33 | template<typename Tuple> | ||
918 | 34 | class CommandArgInstance { | ||
919 | 35 | public: | ||
920 | 36 | virtual int get_index() const = 0; | ||
921 | 37 | virtual const CommandArg<Tuple>* get_arg() const = 0; | ||
922 | 38 | virtual void insertValue(Tuple& t) = 0; | ||
923 | 39 | virtual bool isSet(Tuple& t) const = 0; | ||
924 | 40 | }; | ||
925 | 41 | |||
926 | 42 | template<typename T, int Idx, typename Tuple> | ||
927 | 43 | class TypedCommandArgInstance : public CommandArgInstance<Tuple> | ||
928 | 44 | { | ||
929 | 45 | public: | ||
930 | 46 | TypedCommandArgInstance(T aValue, const CommandArg<Tuple>* aArg) | ||
931 | 47 | : theValue(aValue), theArg(aArg) | ||
932 | 48 | { | ||
933 | 49 | } | ||
934 | 50 | |||
935 | 51 | virtual int | ||
936 | 52 | get_index() const | ||
937 | 53 | { | ||
938 | 54 | return Idx; | ||
939 | 55 | } | ||
940 | 56 | |||
941 | 57 | virtual const CommandArg<Tuple>* | ||
942 | 58 | get_arg() const | ||
943 | 59 | { | ||
944 | 60 | return theArg; | ||
945 | 61 | } | ||
946 | 62 | |||
947 | 63 | virtual void | ||
948 | 64 | insertValue(Tuple& t) | ||
949 | 65 | { | ||
950 | 66 | ZORBA_TR1_NS::get<Idx>(t).first = true; | ||
951 | 67 | ZORBA_TR1_NS::get<Idx>(t).second = theValue; | ||
952 | 68 | } | ||
953 | 69 | |||
954 | 70 | virtual bool isSet(Tuple& t) const | ||
955 | 71 | { | ||
956 | 72 | return ZORBA_TR1_NS::get<Idx>(t).first; | ||
957 | 73 | } | ||
958 | 74 | |||
959 | 75 | private: | ||
960 | 76 | |||
961 | 77 | T theValue; | ||
962 | 78 | const CommandArg<Tuple>* theArg; | ||
963 | 79 | }; | ||
964 | 80 | |||
965 | 81 | template<typename Tuple> | ||
966 | 82 | class CommandArgType | ||
967 | 83 | { | ||
968 | 84 | public: | ||
969 | 85 | virtual CommandArgInstance<Tuple>* | ||
970 | 86 | parse( | ||
971 | 87 | const std::string& str, | ||
972 | 88 | const CommandArg<Tuple>* arg) = 0; | ||
973 | 89 | |||
974 | 90 | virtual bool | ||
975 | 91 | isVoid() const = 0; | ||
976 | 92 | |||
977 | 93 | virtual bool | ||
978 | 94 | isSet(Tuple& t) const = 0; | ||
979 | 95 | |||
980 | 96 | virtual ~CommandArgType() {} | ||
981 | 97 | }; | ||
982 | 98 | |||
983 | 99 | template<typename T, int Idx, typename Tuple> | ||
984 | 100 | class TypedCommandArgType : public CommandArgType<Tuple> { | ||
985 | 101 | public: | ||
986 | 102 | typedef T Type; | ||
987 | 103 | public: // implementation | ||
988 | 104 | TypedCommandArgType(bool aIsVoid) : theIsVoid(aIsVoid) {} | ||
989 | 105 | TypedCommandArgType(const T& aValue, | ||
990 | 106 | bool aIsVoid) | ||
991 | 107 | : theDefault(aValue), theIsVoid(aIsVoid) {} | ||
992 | 108 | virtual CommandArgInstance<Tuple>* parse(const std::string& str, | ||
993 | 109 | const CommandArg<Tuple>* arg) | ||
994 | 110 | { | ||
995 | 111 | T aValue; | ||
996 | 112 | |||
997 | 113 | // special treatment for strings | ||
998 | 114 | // this is a double hack: | ||
999 | 115 | // - we check the type name if this starts with: class std::basic_string | ||
1000 | 116 | // - we use void* in readEntireString to workaround the template type T | ||
1001 | 117 | // which would otherwise complain during compilation if types and | ||
1002 | 118 | // operators do not match | ||
1003 | 119 | // TOSO: probably someone can find a more elegant solution | ||
1004 | 120 | std::string lTypeName(typeid(T).name()); | ||
1005 | 121 | if (lTypeName.find("class std::basic_string") == 0) { | ||
1006 | 122 | readEntireString(str, &aValue); | ||
1007 | 123 | } else { | ||
1008 | 124 | std::stringstream stream(str); | ||
1009 | 125 | std::stringstream out; | ||
1010 | 126 | stream >> aValue; | ||
1011 | 127 | if (stream.fail()) { | ||
1012 | 128 | std::cerr << "Error: Could not parse value \"" << str << "\" as type " | ||
1013 | 129 | << typeid(T).name() | ||
1014 | 130 | << std::endl; | ||
1015 | 131 | return 0; | ||
1016 | 132 | } | ||
1017 | 133 | } | ||
1018 | 134 | |||
1019 | 135 | return new TypedCommandArgInstance<T, Idx, Tuple>(aValue, arg); | ||
1020 | 136 | } | ||
1021 | 137 | virtual bool isVoid() const { return theIsVoid; } | ||
1022 | 138 | virtual bool isSet(Tuple& t) const | ||
1023 | 139 | { | ||
1024 | 140 | return ZORBA_TR1_NS::get<Idx>(t).first; | ||
1025 | 141 | } | ||
1026 | 142 | private: | ||
1027 | 143 | void readEntireString(std::string aIn, void* aValue) | ||
1028 | 144 | { | ||
1029 | 145 | *((std::string*)aValue) = aIn; | ||
1030 | 146 | } | ||
1031 | 147 | |||
1032 | 148 | TypedCommandArgType<T, Idx, Tuple>() {} | ||
1033 | 149 | T theDefault; | ||
1034 | 150 | bool theIsVoid; | ||
1035 | 151 | }; | ||
1036 | 152 | |||
1037 | 153 | template<typename Tuple> | ||
1038 | 154 | class CommandArg { | ||
1039 | 155 | public: | ||
1040 | 156 | CommandArg(unsigned aId, | ||
1041 | 157 | CommandArgType<Tuple>* aType, | ||
1042 | 158 | const std::set<std::string>& aNames, | ||
1043 | 159 | const std::string& aDescription, | ||
1044 | 160 | bool aIsRequired) | ||
1045 | 161 | : theId(aId), | ||
1046 | 162 | theType(aType), | ||
1047 | 163 | theNames(aNames), | ||
1048 | 164 | theDescription(aDescription), | ||
1049 | 165 | theIsRequired(aIsRequired) | ||
1050 | 166 | { | ||
1051 | 167 | } | ||
1052 | 168 | |||
1053 | 169 | ~CommandArg() | ||
1054 | 170 | { | ||
1055 | 171 | delete theType; | ||
1056 | 172 | } | ||
1057 | 173 | |||
1058 | 174 | unsigned | ||
1059 | 175 | get_id() const | ||
1060 | 176 | { | ||
1061 | 177 | return theId; | ||
1062 | 178 | } | ||
1063 | 179 | |||
1064 | 180 | bool | ||
1065 | 181 | canHandle(const std::string& arg) const | ||
1066 | 182 | { | ||
1067 | 183 | if (theNames.find(arg) != theNames.end()) { | ||
1068 | 184 | return true; | ||
1069 | 185 | } | ||
1070 | 186 | return false; | ||
1071 | 187 | } | ||
1072 | 188 | |||
1073 | 189 | CommandArgInstance<Tuple>* | ||
1074 | 190 | parse(const std::string& str) const | ||
1075 | 191 | { | ||
1076 | 192 | return theType->parse(str, this); | ||
1077 | 193 | } | ||
1078 | 194 | |||
1079 | 195 | bool | ||
1080 | 196 | isVoid() const | ||
1081 | 197 | { | ||
1082 | 198 | return theType->isVoid(); | ||
1083 | 199 | } | ||
1084 | 200 | |||
1085 | 201 | bool | ||
1086 | 202 | isRequired() const | ||
1087 | 203 | { | ||
1088 | 204 | return theIsRequired; | ||
1089 | 205 | } | ||
1090 | 206 | |||
1091 | 207 | std::string | ||
1092 | 208 | getName() const | ||
1093 | 209 | { | ||
1094 | 210 | return *(theNames.begin()); | ||
1095 | 211 | } | ||
1096 | 212 | |||
1097 | 213 | std::string | ||
1098 | 214 | getDescription() const | ||
1099 | 215 | { | ||
1100 | 216 | return theDescription; | ||
1101 | 217 | } | ||
1102 | 218 | |||
1103 | 219 | bool | ||
1104 | 220 | isSet(Tuple& t) const | ||
1105 | 221 | { | ||
1106 | 222 | return theType->isSet(t); | ||
1107 | 223 | } | ||
1108 | 224 | |||
1109 | 225 | private: | ||
1110 | 226 | |||
1111 | 227 | unsigned theId; | ||
1112 | 228 | CommandArgType<Tuple>* theType; | ||
1113 | 229 | std::set<std::string> theNames; | ||
1114 | 230 | std::string theDescription; | ||
1115 | 231 | bool theIsRequired; | ||
1116 | 232 | }; | ||
1117 | 233 | |||
1118 | 234 | } // namespace zorba | ||
1119 | 235 | } // namespace debugger | ||
1120 | 236 | |||
1121 | 237 | #endif // ZORBA_DEBUGGER_COMMAND_ARG_H | ||
1122 | 0 | 238 | ||
1123 | === modified file 'bin/debugger/command_line_handler.cpp' | |||
1124 | --- bin/debug_client/command_line_handler.cpp 2011-07-01 01:53:24 +0000 | |||
1125 | +++ bin/debugger/command_line_handler.cpp 2011-12-20 18:15:30 +0000 | |||
1126 | @@ -1,4 +1,4 @@ | |||
1128 | 1 | /* | 1 | /* |
1129 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | 2 | * Copyright 2006-2008 The FLWOR Foundation. |
1130 | 3 | * | 3 | * |
1131 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
1132 | @@ -23,225 +23,372 @@ | |||
1133 | 23 | # define msleep Sleep | 23 | # define msleep Sleep |
1134 | 24 | #endif | 24 | #endif |
1135 | 25 | 25 | ||
1137 | 26 | namespace zorba { namespace debugclient { | 26 | namespace zorba { namespace debugger { |
1138 | 27 | 27 | ||
1139 | 28 | using namespace ::std; | ||
1140 | 29 | using namespace ::ZORBA_TR1_NS; | 28 | using namespace ::ZORBA_TR1_NS; |
1141 | 30 | 29 | ||
1147 | 31 | CommandLineHandler::CommandLineHandler(unsigned short port, | 30 | CommandLineHandler::CommandLineHandler( |
1148 | 32 | LockFreeConsumer<std::size_t>& aConsumer, | 31 | unsigned short port, |
1149 | 33 | LockFreeConsumer<bool>& aContinueQueue, | 32 | LockFreeConsumer<std::size_t>& aConsumer, |
1150 | 34 | EventHandler& aHandler, | 33 | LockFreeConsumer<bool>& aContinueQueue, |
1151 | 35 | CommandLine& aCommandLine) | 34 | EventHandler& aHandler, |
1152 | 35 | CommandPrompt& aCommandPrompt) | ||
1153 | 36 | : theConsumer(aConsumer), | 36 | : theConsumer(aConsumer), |
1154 | 37 | theContinueQueue(aContinueQueue), | 37 | theContinueQueue(aContinueQueue), |
1155 | 38 | theClient(DebuggerClient::createDebuggerClient(&aHandler, port, "localhost")), | 38 | theClient(DebuggerClient::createDebuggerClient(&aHandler, port, "localhost")), |
1158 | 39 | theCommandLine(aCommandLine), | 39 | theCommandLine(aCommandPrompt), |
1159 | 40 | theQuit(false), theContinue(false), theWaitFor(0) | 40 | theQuit(false), theTerminated(true), theContinue(false), theWaitFor(0) |
1160 | 41 | { | 41 | { |
1161 | 42 | addCommands(); | 42 | addCommands(); |
1162 | 43 | } | 43 | } |
1163 | 44 | 44 | ||
1167 | 45 | CommandLineHandler::~CommandLineHandler() | 45 | CommandLineHandler::~CommandLineHandler() |
1168 | 46 | { | 46 | { |
1169 | 47 | } | 47 | } |
1170 | 48 | 48 | ||
1176 | 49 | void CommandLineHandler::execute() | 49 | void |
1177 | 50 | { | 50 | CommandLineHandler::execute() |
1178 | 51 | theClient->accept(); | 51 | { |
1179 | 52 | std::set<std::size_t> lIdList; | 52 | theClient->accept(); |
1180 | 53 | do { | 53 | std::set<std::size_t> lIdList; |
1181 | 54 | do { | ||
1182 | 55 | getNextId(lIdList); | ||
1183 | 56 | while (lIdList.find(theWaitFor) == lIdList.end()) { | ||
1184 | 54 | getNextId(lIdList); | 57 | getNextId(lIdList); |
1220 | 55 | while (!theQuit && lIdList.find(theWaitFor) == lIdList.end()) { | 58 | msleep(20); |
1221 | 56 | getNextId(lIdList); | 59 | } |
1222 | 57 | msleep(20); | 60 | bool lCanQuit; |
1223 | 58 | } | 61 | while (!theContinueQueue.consume(lCanQuit)) { |
1224 | 59 | while (!theContinueQueue.consume(theQuit)) { | 62 | msleep(20); |
1225 | 60 | msleep(20); | 63 | } |
1226 | 61 | } | 64 | if (lCanQuit) { |
1227 | 62 | theQuit = !theQuit; | 65 | theTerminated = true; |
1228 | 63 | if (!theQuit) { | 66 | } |
1229 | 64 | theCommandLine.execute(); | 67 | theCommandLine.execute(); |
1230 | 65 | while (theContinue) { | 68 | while (theContinue) { |
1231 | 66 | theContinue = false; | 69 | theContinue = false; |
1232 | 67 | theCommandLine.execute(); | 70 | theCommandLine.execute(); |
1233 | 68 | } | 71 | } |
1234 | 69 | } | 72 | } while (!theQuit); |
1235 | 70 | } while (!theQuit); | 73 | } |
1236 | 71 | } | 74 | |
1237 | 72 | 75 | void | |
1238 | 73 | void CommandLineHandler::getNextId(std::set<std::size_t>& aIdList) | 76 | CommandLineHandler::getNextId(std::set<std::size_t>& aIdList) |
1239 | 74 | { | 77 | { |
1240 | 75 | std::size_t result; | 78 | std::size_t result; |
1241 | 76 | if (theConsumer.consume(result)) { | 79 | if (theConsumer.consume(result)) { |
1242 | 77 | aIdList.insert(result); | 80 | aIdList.insert(result); |
1243 | 78 | } | 81 | } |
1244 | 79 | } | 82 | } |
1245 | 80 | 83 | ||
1246 | 81 | template<> | 84 | template<> |
1247 | 82 | void CommandLineHandler::handle<Status>(ZORBA_TR1_NS::tuple<> &t) | 85 | void |
1248 | 83 | { | 86 | CommandLineHandler::handle<Status>(ZORBA_TR1_NS::tuple<> &t) |
1249 | 84 | theWaitFor = theClient->status(); | 87 | { |
1250 | 85 | } | 88 | theWaitFor = theClient->status(); |
1251 | 86 | 89 | } | |
1252 | 87 | template<> | 90 | |
1253 | 88 | void CommandLineHandler::handle<Quit>(ZORBA_TR1_NS::tuple<> &t) | 91 | template<> |
1254 | 89 | { | 92 | void |
1255 | 93 | CommandLineHandler::handle<Variables>(ZORBA_TR1_NS::tuple<> &t) | ||
1256 | 94 | { | ||
1257 | 95 | theWaitFor = theClient->variables(); | ||
1258 | 96 | } | ||
1259 | 97 | |||
1260 | 98 | template<> | ||
1261 | 99 | void | ||
1262 | 100 | CommandLineHandler::handle<Quit>(ZORBA_TR1_NS::tuple<> &t) | ||
1263 | 101 | { | ||
1264 | 102 | if (!theTerminated) { | ||
1265 | 90 | bool answered = false; | 103 | bool answered = false; |
1266 | 91 | while (!answered) { | 104 | while (!answered) { |
1267 | 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) "; |
1272 | 93 | char answer; | 106 | std::string lAnswer; |
1273 | 94 | std::cin >> answer; | 107 | std::getline(std::cin, lAnswer); |
1274 | 95 | std::cout << std::endl; | 108 | if (lAnswer == "y" || lAnswer == "yes") { |
1271 | 96 | if (answer == 'y') { | ||
1275 | 97 | answered = true; | 109 | answered = true; |
1277 | 98 | } else if (answered == 'n') { | 110 | } else if (lAnswer == "n" || lAnswer == "no") { |
1278 | 99 | theContinue = true; | 111 | theContinue = true; |
1279 | 100 | return; | 112 | return; |
1280 | 101 | } | 113 | } |
1281 | 102 | } | 114 | } |
1427 | 103 | theWaitFor = theClient->stop(); | 115 | } |
1428 | 104 | theClient->quit(); | 116 | theWaitFor = theClient->stop(); |
1429 | 105 | } | 117 | theClient->quit(); |
1430 | 106 | 118 | theQuit = true; | |
1431 | 107 | template<> | 119 | } |
1432 | 108 | void CommandLineHandler::handle<Run>(ZORBA_TR1_NS::tuple<> &t) | 120 | |
1433 | 109 | { | 121 | template<> |
1434 | 110 | theWaitFor = theClient->run(); | 122 | void |
1435 | 111 | } | 123 | CommandLineHandler::handle<Run>(ZORBA_TR1_NS::tuple<> &t) |
1436 | 112 | 124 | { | |
1437 | 113 | template<> | 125 | theTerminated = false; |
1438 | 114 | void CommandLineHandler::handle<BreakpointSet>(std::tr1::tuple<bstring, bstring, bint> &t) | 126 | theWaitFor = theClient->run(); |
1439 | 115 | { | 127 | } |
1440 | 116 | DebuggerClient::BreakpointType lType = DebuggerClient::Line; | 128 | |
1441 | 117 | bool lEnabled = true; | 129 | template<> |
1442 | 118 | if (get<0>(t).first) { | 130 | void |
1443 | 119 | if (get<0>(t).second == "disabled") { | 131 | CommandLineHandler::handle<BreakpointSet>(std::tr1::tuple<bstring, bstring, bint> &aTuple) |
1444 | 120 | lEnabled = false; | 132 | { |
1445 | 121 | } | 133 | DebuggerClient::BreakpointType lType = DebuggerClient::Line; |
1446 | 122 | } | 134 | bool lEnabled = true; |
1447 | 123 | theWaitFor = theClient->breakpoint_set(lType, | 135 | if (get<0>(aTuple).first) { |
1448 | 124 | lEnabled, | 136 | if (get<0>(aTuple).second == "disabled") { |
1449 | 125 | get<1>(t).second, | 137 | lEnabled = false; |
1450 | 126 | get<2>(t).second); | 138 | } |
1451 | 127 | } | 139 | } |
1452 | 128 | 140 | theWaitFor = theClient->breakpoint_set(lType, | |
1453 | 129 | template<> | 141 | lEnabled, |
1454 | 130 | void CommandLineHandler::handle<BreakpointGet>(tuple<bint> &aTuple) | 142 | get<1>(aTuple).second, |
1455 | 131 | { | 143 | get<2>(aTuple).second); |
1456 | 132 | theWaitFor = theClient->breakpoint_get(get<0>(aTuple).second); | 144 | } |
1457 | 133 | } | 145 | |
1458 | 134 | 146 | template<> | |
1459 | 135 | template<> | 147 | void |
1460 | 136 | void CommandLineHandler::handle<BreakpointDel>(tuple<bint> &aTuple) | 148 | CommandLineHandler::handle<BreakpointGet>(tuple<bint> &aTuple) |
1461 | 137 | { | 149 | { |
1462 | 138 | theWaitFor = theClient->breakpoint_remove(get<0>(aTuple).second); | 150 | theWaitFor = theClient->breakpoint_get(get<0>(aTuple).second); |
1463 | 139 | } | 151 | } |
1464 | 140 | 152 | ||
1465 | 141 | template<> | 153 | template<> |
1466 | 142 | void CommandLineHandler::handle<BreakpointList>(tuple<> &t) | 154 | void |
1467 | 143 | { | 155 | CommandLineHandler::handle<BreakpointRemove>(tuple<bint> &aTuple) |
1468 | 144 | theWaitFor = theClient->breakpoint_list(); | 156 | { |
1469 | 145 | } | 157 | theWaitFor = theClient->breakpoint_remove(get<0>(aTuple).second); |
1470 | 146 | 158 | } | |
1471 | 147 | template<> | 159 | |
1472 | 148 | void CommandLineHandler::handle<StackDepth>(tuple<> &t) | 160 | template<> |
1473 | 149 | { | 161 | void |
1474 | 150 | theWaitFor = theClient->stack_depth(); | 162 | CommandLineHandler::handle<BreakpointList>(tuple<> &aTuple) |
1475 | 151 | } | 163 | { |
1476 | 152 | 164 | theWaitFor = theClient->breakpoint_list(); | |
1477 | 153 | template<> | 165 | } |
1478 | 154 | void CommandLineHandler::handle<StackGet>(tuple<bint> &aTuple) | 166 | |
1479 | 155 | { | 167 | template<> |
1480 | 156 | if (get<0>(aTuple).first) { | 168 | void |
1481 | 157 | theWaitFor = theClient->stack_get(get<0>(aTuple).second); | 169 | CommandLineHandler::handle<StackDepth>(tuple<> &aTuple) |
1482 | 158 | } else { | 170 | { |
1483 | 159 | theWaitFor = theClient->stack_get(); | 171 | theWaitFor = theClient->stack_depth(); |
1484 | 160 | } | 172 | } |
1485 | 161 | } | 173 | |
1486 | 162 | 174 | template<> | |
1487 | 163 | template<> | 175 | void |
1488 | 164 | void CommandLineHandler::handle<ContextNames>(tuple<>& aTuple) | 176 | CommandLineHandler::handle<StackGet>(tuple<bint> &aTuple) |
1489 | 165 | { | 177 | { |
1490 | 166 | theWaitFor = theClient->context_names(); | 178 | if (get<0>(aTuple).first) { |
1491 | 167 | } | 179 | theWaitFor = theClient->stack_get(get<0>(aTuple).second); |
1492 | 168 | 180 | } else { | |
1493 | 169 | template<> | 181 | theWaitFor = theClient->stack_get(); |
1494 | 170 | void CommandLineHandler::handle<ContextGet>(tuple<bint> &aTuple) | 182 | } |
1495 | 171 | { | 183 | } |
1496 | 172 | if (get<0>(aTuple).first) | 184 | |
1497 | 173 | theWaitFor = theClient->context_get(get<0>(aTuple).second); | 185 | template<> |
1498 | 174 | else | 186 | void |
1499 | 175 | theWaitFor = theClient->context_get(); | 187 | CommandLineHandler::handle<ContextNames>(tuple<>& aTuple) |
1500 | 176 | } | 188 | { |
1501 | 177 | 189 | theWaitFor = theClient->context_names(); | |
1502 | 178 | template<> | 190 | } |
1503 | 179 | void CommandLineHandler::handle<Eval>(tuple<bstring>& aTuple) | 191 | |
1504 | 180 | { | 192 | template<> |
1505 | 181 | theWaitFor = theClient->eval(get<0>(aTuple).second); | 193 | void CommandLineHandler::handle<ContextGet>(tuple<bint, bint> &aTuple) |
1506 | 182 | } | 194 | { |
1507 | 183 | 195 | int lDepth = -1; | |
1508 | 184 | void CommandLineHandler::addCommands() | 196 | int lContext = -1; |
1509 | 185 | { | 197 | |
1510 | 186 | theCommandLine << createCommand<Status>(tuple<>(), "status", *this, | 198 | if (get<0>(aTuple).first) { |
1511 | 187 | "Gets the status of the server"); | 199 | lDepth = get<0>(aTuple).second; |
1512 | 188 | theCommandLine << createCommand<Quit>(tuple<>(), "quit", *this, | 200 | } |
1513 | 189 | "Stops debugging and quits the client"); | 201 | if (get<1>(aTuple).first) { |
1514 | 190 | theCommandLine << createCommand<Run>(tuple<>(), "run", *this, "Run the Query"); | 202 | lContext = get<1>(aTuple).second; |
1515 | 191 | { | 203 | } |
1516 | 192 | Command<CommandLineHandler, tuple<bstring, bstring, bint>, BreakpointSet>* lCommand = | 204 | theWaitFor = theClient->context_get(lDepth, lContext); |
1517 | 193 | createCommand<BreakpointSet>(tuple<bstring, bstring, bint>(), "break", *this, "Set a breakpoint"); | 205 | } |
1518 | 194 | (*lCommand)(0, "s", createArgType<tuple<bstring, bstring, bint>, std::string, 0>(tuple<bstring, bstring, bint>()), | 206 | |
1519 | 195 | "breakpoint state (enabled or disabled - default: enabled)", false); | 207 | template<> |
1520 | 196 | (*lCommand)(1, "f", createArgType<tuple<bstring, bstring, bint>, std::string, 1>(tuple<bstring, bstring, bint>()), | 208 | void CommandLineHandler::handle<Source>(tuple<bint, bint, bstring> &aTuple) |
1521 | 197 | "The name of the file where to stop", true); | 209 | { |
1522 | 198 | (*lCommand)(2, "l", createArgType<tuple<bstring, bstring, bint>, int, 2>(tuple<bstring, bstring, bint>()), | 210 | theWaitFor = theClient->source( |
1523 | 199 | "The line number", true); | 211 | get<2>(aTuple).second, |
1524 | 200 | 212 | get<0>(aTuple).second, | |
1525 | 201 | theCommandLine << lCommand; | 213 | get<1>(aTuple).second); |
1526 | 202 | } | 214 | } |
1527 | 203 | { | 215 | |
1528 | 204 | Command<CommandLineHandler, tuple<bint>, BreakpointGet>* lCommand | 216 | template<> |
1529 | 205 | = createCommand<BreakpointGet>(tuple<bint>(), "binfo", *this, | 217 | void CommandLineHandler::handle<Eval>(tuple<bstring>& aTuple) |
1530 | 206 | "Get information about a given breakpoint"); | 218 | { |
1531 | 207 | (*lCommand)(0, "i", createArgType<tuple<bint>, int, 0>(tuple<bint>()), | 219 | theWaitFor = theClient->eval(get<0>(aTuple).second); |
1532 | 208 | "The id of the breakpoint", true); | 220 | } |
1533 | 209 | 221 | ||
1534 | 210 | theCommandLine << lCommand; | 222 | template<> |
1535 | 211 | } | 223 | void |
1536 | 212 | { | 224 | CommandLineHandler::handle<StepIn>(ZORBA_TR1_NS::tuple<> &t) |
1537 | 213 | Command<CommandLineHandler, tuple<bint>, BreakpointDel>* lCommand | 225 | { |
1538 | 214 | = createCommand<BreakpointDel>(tuple<bint>(), "bdel", *this, "Delete a breakpoint with a given id"); | 226 | theTerminated = false; |
1539 | 215 | (*lCommand)(0, "i", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The id of the breakpoint", true); | 227 | theWaitFor = theClient->step_into(); |
1540 | 216 | 228 | } | |
1541 | 217 | theCommandLine << lCommand; | 229 | |
1542 | 218 | } | 230 | template<> |
1543 | 219 | theCommandLine << createCommand<BreakpointList>(tuple<>(), "blist", *this, "List all set breakpoints"); | 231 | void |
1544 | 220 | theCommandLine << createCommand<StackDepth>(tuple<>(), "sdepth", *this, "Get the depth of the stack"); | 232 | CommandLineHandler::handle<StepOut>(ZORBA_TR1_NS::tuple<> &t) |
1545 | 221 | { | 233 | { |
1546 | 222 | Command<CommandLineHandler, tuple<bint>, StackGet>* lCommand | 234 | theWaitFor = theClient->step_out(); |
1547 | 223 | = createCommand<StackGet>(tuple<bint>(), "sget", *this, "Get information about one or all stack frames"); | 235 | } |
1548 | 224 | (*lCommand)(0, "d", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The stack entry two show (show all if not provided)", false); | 236 | |
1549 | 225 | theCommandLine << lCommand; | 237 | template<> |
1550 | 226 | } | 238 | void |
1551 | 227 | theCommandLine << createCommand<ContextNames>(tuple<>(), "cnames", *this, "Get the names of the avilable contexts"); | 239 | CommandLineHandler::handle<StepOver>(ZORBA_TR1_NS::tuple<> &t) |
1552 | 228 | { | 240 | { |
1553 | 229 | Command<CommandLineHandler, tuple<bint>, ContextGet>* lCommand | 241 | theTerminated = false; |
1554 | 230 | = createCommand<ContextGet>(tuple<bint>(), "cget", *this, "Get a context"); | 242 | theWaitFor = theClient->step_over(); |
1555 | 231 | 243 | } | |
1556 | 232 | (*lCommand)(0, "c", createArgType<tuple<bint>, int, 0>(tuple<bint>()), "The id of the context", false); | 244 | |
1557 | 233 | 245 | void | |
1558 | 234 | theCommandLine << lCommand; | 246 | CommandLineHandler::addCommands() |
1559 | 235 | } | 247 | { |
1560 | 236 | { | 248 | typedef tuple<> TUPLE; |
1561 | 237 | Command<CommandLineHandler, tuple<bstring>, Eval>* lCommand | 249 | typedef tuple<bint> TUPLE_INT; |
1562 | 238 | = createCommand<Eval>(tuple<bstring>(), "eval", *this, "Evaluate a function"); | 250 | typedef tuple<bstring> TUPLE_STR; |
1563 | 239 | 251 | typedef tuple<bint, bint> TUPLE_INT_INT; | |
1564 | 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; |
1565 | 241 | 253 | typedef tuple<bint, bint, bstring> TUPLE_INT_INT_STR; | |
1566 | 242 | theCommandLine << lCommand; | 254 | |
1567 | 243 | } | 255 | // DBGP: status |
1568 | 244 | } | 256 | theCommandLine << createCommand<Status>(TUPLE(), "status", *this, "Gets the status of the server"); |
1569 | 245 | 257 | ||
1570 | 246 | }} // namespace zorba::debugclient | 258 | // ALIAS: variables (context_get -c -1) |
1571 | 247 | 259 | { | |
1572 | 260 | std::set<std::string> lAliases; | ||
1573 | 261 | lAliases.insert("vars"); | ||
1574 | 262 | theCommandLine << createCommand<Variables>(TUPLE(), "variables", lAliases, *this, "Gets the variables visible in the current scope"); | ||
1575 | 263 | } | ||
1576 | 264 | |||
1577 | 265 | // META: quit | ||
1578 | 266 | theCommandLine << createCommand<Quit>(TUPLE(), "quit", *this, "Stops debugging and quits the client"); | ||
1579 | 267 | |||
1580 | 268 | // DBGP: run | ||
1581 | 269 | theCommandLine << createCommand<Run>(TUPLE(), "run", *this, "Run the query"); | ||
1582 | 270 | |||
1583 | 271 | // DBGP: breakpoint_set | ||
1584 | 272 | { | ||
1585 | 273 | std::set<std::string> lAliases; | ||
1586 | 274 | lAliases.insert("break"); | ||
1587 | 275 | Command<CommandLineHandler, TUPLE_STR_STR_INT, BreakpointSet>* lCommand = | ||
1588 | 276 | createCommand<BreakpointSet>(TUPLE_STR_STR_INT(), "bset", lAliases, *this, "Set a breakpoint"); | ||
1589 | 277 | |||
1590 | 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); | ||
1591 | 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); | ||
1592 | 280 | lCommand->addArgument(2, "l", createArgType<TUPLE_STR_STR_INT, int, 2>(TUPLE_STR_STR_INT()), "line number", true); | ||
1593 | 281 | |||
1594 | 282 | theCommandLine << lCommand; | ||
1595 | 283 | } | ||
1596 | 284 | |||
1597 | 285 | // DBGP: breakpoint_get | ||
1598 | 286 | { | ||
1599 | 287 | Command<CommandLineHandler, TUPLE_INT, BreakpointGet>* lCommand = | ||
1600 | 288 | createCommand<BreakpointGet>(TUPLE_INT(), "bget", *this, "Get information about a given breakpoint"); | ||
1601 | 289 | |||
1602 | 290 | lCommand->addArgument(0, "d", createArgType<TUPLE_INT, int, 0>(TUPLE_INT()), "breakpoint ID", true); | ||
1603 | 291 | |||
1604 | 292 | theCommandLine << lCommand; | ||
1605 | 293 | } | ||
1606 | 294 | |||
1607 | 295 | // DBGP: breakpoint_remove | ||
1608 | 296 | { | ||
1609 | 297 | std::set<std::string> lAliases; | ||
1610 | 298 | lAliases.insert("clear"); | ||
1611 | 299 | lAliases.insert("delete"); | ||
1612 | 300 | Command<CommandLineHandler, TUPLE_INT, BreakpointRemove>* lCommand = | ||
1613 | 301 | createCommand<BreakpointRemove>(TUPLE_INT(), "bremove", lAliases, *this, "Delete a breakpoint"); | ||
1614 | 302 | |||
1615 | 303 | lCommand->addArgument(0, "d", createArgType<TUPLE_INT, int, 0>(TUPLE_INT()), "breakpoint ID", true); | ||
1616 | 304 | |||
1617 | 305 | theCommandLine << lCommand; | ||
1618 | 306 | } | ||
1619 | 307 | |||
1620 | 308 | // DBGP: breakpoint_list | ||
1621 | 309 | theCommandLine << createCommand<BreakpointList>(TUPLE(), "blist", *this, "List all set breakpoints"); | ||
1622 | 310 | |||
1623 | 311 | // DBGP: stack_depth | ||
1624 | 312 | theCommandLine << createCommand<StackDepth>(TUPLE(), "sdepth", *this, "Get the depth of the stack"); | ||
1625 | 313 | |||
1626 | 314 | // DBGP: stack_get | ||
1627 | 315 | { | ||
1628 | 316 | Command<CommandLineHandler, TUPLE_INT, StackGet>* lCommand = | ||
1629 | 317 | createCommand<StackGet>(TUPLE_INT(), "sget", *this, "Get information about one or all stack frames"); | ||
1630 | 318 | |||
1631 | 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); | ||
1632 | 320 | |||
1633 | 321 | theCommandLine << lCommand; | ||
1634 | 322 | } | ||
1635 | 323 | |||
1636 | 324 | // DBGP: context_names | ||
1637 | 325 | theCommandLine << createCommand<ContextNames>(tuple<>(), "cnames", *this, "Get the names of the avilable contexts"); | ||
1638 | 326 | // the DBGP -d arguments for this command is omitted since we always have/return: 0 - Local, 1 - Global | ||
1639 | 327 | |||
1640 | 328 | // DBGP: context_get | ||
1641 | 329 | { | ||
1642 | 330 | Command<CommandLineHandler, TUPLE_INT_INT, ContextGet>* lCommand = | ||
1643 | 331 | createCommand<ContextGet>(TUPLE_INT_INT(), "cget", *this, "Get a context (list variables in this context)"); | ||
1644 | 332 | |||
1645 | 333 | lCommand->addArgument(0, "d", createArgType<TUPLE_INT_INT, int, 0>(TUPLE_INT_INT()), "stack depth (optional, default: 0)", false); | ||
1646 | 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); | ||
1647 | 335 | |||
1648 | 336 | theCommandLine << lCommand; | ||
1649 | 337 | } | ||
1650 | 338 | |||
1651 | 339 | // DBGP: source | ||
1652 | 340 | { | ||
1653 | 341 | std::set<std::string> lAliases; | ||
1654 | 342 | lAliases.insert("list"); | ||
1655 | 343 | Command<CommandLineHandler, TUPLE_INT_INT_STR, Source>* lCommand = | ||
1656 | 344 | createCommand<Source>(TUPLE_INT_INT_STR(), "source", lAliases, *this, "List source code"); | ||
1657 | 345 | |||
1658 | 346 | lCommand->addArgument(0, "b", createArgType<TUPLE_INT_INT_STR, int, 0>(TUPLE_INT_INT_STR()), "begin line (optional, default: first line)", false); | ||
1659 | 347 | lCommand->addArgument(1, "e", createArgType<TUPLE_INT_INT_STR, int, 1>(TUPLE_INT_INT_STR()), "end line (optional, default: last line)", false); | ||
1660 | 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); | ||
1661 | 349 | |||
1662 | 350 | theCommandLine << lCommand; | ||
1663 | 351 | } | ||
1664 | 352 | |||
1665 | 353 | // DBGP: eval | ||
1666 | 354 | { | ||
1667 | 355 | std::set<std::string> lAliases; | ||
1668 | 356 | lAliases.insert("print"); | ||
1669 | 357 | Command<CommandLineHandler, TUPLE_STR, Eval>* lCommand = | ||
1670 | 358 | createCommand<Eval>(TUPLE_STR(), "eval", lAliases, *this, "Evaluate an expression"); | ||
1671 | 359 | |||
1672 | 360 | // TODO: this argument should not be here at all. Eval has the form: eval -i transaction_id -- {DATA} | ||
1673 | 361 | // Eval should be called with a command like: eval 1 + 3 | ||
1674 | 362 | // - no need for an argument name | ||
1675 | 363 | // - everything following the fist contiguous set of whitespaces are sent as string | ||
1676 | 364 | lCommand->addArgument(0, "c", createArgType<TUPLE_STR, std::string, 0>(TUPLE_STR()), "expression to evaluate", true); | ||
1677 | 365 | |||
1678 | 366 | theCommandLine << lCommand; | ||
1679 | 367 | } | ||
1680 | 368 | |||
1681 | 369 | // DBGP: step_in | ||
1682 | 370 | { | ||
1683 | 371 | std::set<std::string> lAliases; | ||
1684 | 372 | lAliases.insert("step"); | ||
1685 | 373 | lAliases.insert("s"); | ||
1686 | 374 | theCommandLine << createCommand<StepIn>(TUPLE(), "in", lAliases, *this, "Step in"); | ||
1687 | 375 | } | ||
1688 | 376 | |||
1689 | 377 | // DBGP: step_out | ||
1690 | 378 | { | ||
1691 | 379 | std::set<std::string> lAliases; | ||
1692 | 380 | lAliases.insert("finish"); | ||
1693 | 381 | theCommandLine << createCommand<StepOut>(TUPLE(), "out", lAliases, *this, "Step out"); | ||
1694 | 382 | } | ||
1695 | 383 | |||
1696 | 384 | // DBGP: step_over | ||
1697 | 385 | { | ||
1698 | 386 | std::set<std::string> lAliases; | ||
1699 | 387 | lAliases.insert("next"); | ||
1700 | 388 | lAliases.insert("n"); | ||
1701 | 389 | theCommandLine << createCommand<StepOver>(TUPLE(), "over", lAliases, *this, "Step over"); | ||
1702 | 390 | } | ||
1703 | 391 | } | ||
1704 | 392 | |||
1705 | 393 | } // namespace zorba | ||
1706 | 394 | } // namespace debugger | ||
1707 | 248 | 395 | ||
1708 | === modified file 'bin/debugger/command_line_handler.h' | |||
1709 | --- bin/debug_client/command_line_handler.h 2011-07-01 01:53:24 +0000 | |||
1710 | +++ bin/debugger/command_line_handler.h 2011-12-20 18:15:30 +0000 | |||
1711 | @@ -14,46 +14,69 @@ | |||
1712 | 14 | * limitations under the License. | 14 | * limitations under the License. |
1713 | 15 | */ | 15 | */ |
1714 | 16 | #pragma once | 16 | #pragma once |
1715 | 17 | #ifndef ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H | ||
1716 | 18 | #define ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H | ||
1717 | 17 | 19 | ||
1718 | 18 | #include <set> | 20 | #include <set> |
1719 | 19 | #include <cassert> | 21 | #include <cassert> |
1720 | 22 | |||
1721 | 20 | #include <zorba/debugger_client.h> | 23 | #include <zorba/debugger_client.h> |
1723 | 21 | #include "debug_command.h" | 24 | |
1724 | 25 | #include "command.h" | ||
1725 | 26 | #include "command_prompt.h" | ||
1726 | 22 | #include "event_handler.h" | 27 | #include "event_handler.h" |
1727 | 23 | 28 | ||
1730 | 24 | namespace zorba { namespace debugclient { | 29 | |
1731 | 25 | 30 | namespace zorba { namespace debugger { | |
1732 | 31 | |||
1733 | 26 | enum Commands { | 32 | enum Commands { |
1734 | 27 | Status, | 33 | Status, |
1735 | 34 | Variables, | ||
1736 | 35 | Quit, | ||
1737 | 28 | Run, | 36 | Run, |
1738 | 29 | BreakpointSet, | 37 | BreakpointSet, |
1739 | 30 | BreakpointGet, | 38 | BreakpointGet, |
1741 | 31 | BreakpointDel, | 39 | BreakpointRemove, |
1742 | 32 | BreakpointList, | 40 | BreakpointList, |
1743 | 33 | StackDepth, | 41 | StackDepth, |
1744 | 34 | StackGet, | 42 | StackGet, |
1745 | 35 | ContextNames, | 43 | ContextNames, |
1746 | 36 | ContextGet, | 44 | ContextGet, |
1747 | 45 | Source, | ||
1748 | 37 | Eval, | 46 | Eval, |
1750 | 38 | Quit | 47 | StepIn, |
1751 | 48 | StepOut, | ||
1752 | 49 | StepOver | ||
1753 | 39 | }; | 50 | }; |
1754 | 40 | 51 | ||
1756 | 41 | class CommandLineHandler { | 52 | class CommandLineHandler |
1757 | 53 | { | ||
1758 | 42 | private: | 54 | private: |
1759 | 55 | |||
1760 | 43 | typedef std::pair<bool, std::string> bstring; | 56 | typedef std::pair<bool, std::string> bstring; |
1761 | 44 | typedef std::pair<bool, int> bint; | 57 | typedef std::pair<bool, int> bint; |
1762 | 58 | |||
1763 | 45 | public: | 59 | public: |
1769 | 46 | CommandLineHandler(unsigned short port, | 60 | |
1770 | 47 | LockFreeConsumer<std::size_t>& aConsumer, | 61 | CommandLineHandler( |
1771 | 48 | LockFreeConsumer<bool>& aContinueQueue, | 62 | unsigned short port, |
1772 | 49 | EventHandler& aHandler, | 63 | LockFreeConsumer<std::size_t>& aConsumer, |
1773 | 50 | CommandLine& aCommandLine); | 64 | LockFreeConsumer<bool>& aContinueQueue, |
1774 | 65 | EventHandler& aHandler, | ||
1775 | 66 | CommandPrompt& aCommandPrompt); | ||
1776 | 67 | |||
1777 | 51 | ~CommandLineHandler(); | 68 | ~CommandLineHandler(); |
1778 | 69 | |||
1779 | 52 | public: | 70 | public: |
1780 | 53 | void execute(); | 71 | void execute(); |
1781 | 72 | |||
1782 | 54 | public: // Handlers | 73 | public: // Handlers |
1783 | 74 | |||
1784 | 55 | template<int> | 75 | template<int> |
1786 | 56 | void handle(ZORBA_TR1_NS::tuple<>& aTuple) { assert(false); } | 76 | void handle(ZORBA_TR1_NS::tuple<>& aTuple) |
1787 | 77 | { | ||
1788 | 78 | assert(false); | ||
1789 | 79 | } | ||
1790 | 57 | 80 | ||
1791 | 58 | template<int> | 81 | template<int> |
1792 | 59 | void handle(ZORBA_TR1_NS::tuple<bstring, bstring, bint>& t) | 82 | void handle(ZORBA_TR1_NS::tuple<bstring, bstring, bint>& t) |
1793 | @@ -62,63 +85,93 @@ | |||
1794 | 62 | } | 85 | } |
1795 | 63 | 86 | ||
1796 | 64 | template<int> | 87 | template<int> |
1797 | 88 | void handle(ZORBA_TR1_NS::tuple<bint, bint, bstring>& t) | ||
1798 | 89 | { | ||
1799 | 90 | assert(false); | ||
1800 | 91 | } | ||
1801 | 92 | |||
1802 | 93 | template<int> | ||
1803 | 65 | void handle(ZORBA_TR1_NS::tuple<bint>& aTuple) | 94 | void handle(ZORBA_TR1_NS::tuple<bint>& aTuple) |
1804 | 66 | { | 95 | { |
1805 | 67 | assert(false); | 96 | assert(false); |
1806 | 68 | } | 97 | } |
1807 | 69 | 98 | ||
1808 | 70 | template<int> | 99 | template<int> |
1809 | 100 | void handle(ZORBA_TR1_NS::tuple<bint, bint>& aTuple) | ||
1810 | 101 | { | ||
1811 | 102 | assert(false); | ||
1812 | 103 | } | ||
1813 | 104 | |||
1814 | 105 | template<int> | ||
1815 | 71 | void handle(ZORBA_TR1_NS::tuple<bstring>& aTuple) | 106 | void handle(ZORBA_TR1_NS::tuple<bstring>& aTuple) |
1816 | 72 | { | 107 | { |
1817 | 73 | assert(false); | 108 | assert(false); |
1818 | 74 | } | 109 | } |
1819 | 110 | |||
1820 | 75 | private: | 111 | private: |
1828 | 76 | LockFreeConsumer<std::size_t>& theConsumer; | 112 | LockFreeConsumer<std::size_t>& theConsumer; |
1829 | 77 | LockFreeConsumer<bool>& theContinueQueue; | 113 | LockFreeConsumer<bool>& theContinueQueue; |
1830 | 78 | DebuggerClient* theClient; | 114 | DebuggerClient* theClient; |
1831 | 79 | CommandLine& theCommandLine; | 115 | CommandPrompt& theCommandLine; |
1832 | 80 | bool theQuit; | 116 | bool theQuit; |
1833 | 81 | bool theContinue; | 117 | bool theTerminated; |
1834 | 82 | std::size_t theWaitFor; | 118 | bool theContinue; |
1835 | 119 | std::size_t theWaitFor; | ||
1836 | 120 | |||
1837 | 83 | private: | 121 | private: |
1838 | 84 | void getNextId(std::set<std::size_t>& aIdList); | 122 | void getNextId(std::set<std::size_t>& aIdList); |
1839 | 85 | void addCommands(); | 123 | void addCommands(); |
1879 | 86 | }; | 124 | }; |
1880 | 87 | 125 | ||
1881 | 88 | template<> | 126 | template<> |
1882 | 89 | void CommandLineHandler::handle<Status> (ZORBA_TR1_NS::tuple<>& t); | 127 | void CommandLineHandler::handle<Status> (ZORBA_TR1_NS::tuple<>& t); |
1883 | 90 | 128 | ||
1884 | 91 | template<> | 129 | template<> |
1885 | 92 | void CommandLineHandler::handle<Quit> (ZORBA_TR1_NS::tuple<>& t); | 130 | void CommandLineHandler::handle<Quit> (ZORBA_TR1_NS::tuple<>& t); |
1886 | 93 | 131 | ||
1887 | 94 | template<> | 132 | template<> |
1888 | 95 | void CommandLineHandler::handle<Run> (ZORBA_TR1_NS::tuple<> &t); | 133 | void CommandLineHandler::handle<Run> (ZORBA_TR1_NS::tuple<> &t); |
1889 | 96 | 134 | ||
1890 | 97 | template<> | 135 | template<> |
1891 | 98 | void CommandLineHandler::handle<StackDepth> (ZORBA_TR1_NS::tuple<>& t); | 136 | void CommandLineHandler::handle<StackDepth> (ZORBA_TR1_NS::tuple<>& t); |
1892 | 99 | 137 | ||
1893 | 100 | template<> | 138 | template<> |
1894 | 101 | void CommandLineHandler::handle<BreakpointList> (ZORBA_TR1_NS::tuple<>& aTuple); | 139 | void CommandLineHandler::handle<BreakpointList> (ZORBA_TR1_NS::tuple<>& aTuple); |
1895 | 102 | 140 | ||
1896 | 103 | template<> | 141 | template<> |
1897 | 104 | void CommandLineHandler::handle<BreakpointSet> (ZORBA_TR1_NS::tuple<bstring, bstring, bint> &t); | 142 | void CommandLineHandler::handle<BreakpointSet> (ZORBA_TR1_NS::tuple<bstring, bstring, bint> &t); |
1898 | 105 | 143 | ||
1899 | 106 | template<> | 144 | template<> |
1900 | 107 | void CommandLineHandler::handle<BreakpointGet> (ZORBA_TR1_NS::tuple<bint>& aTuple); | 145 | void CommandLineHandler::handle<BreakpointGet> (ZORBA_TR1_NS::tuple<bint>& aTuple); |
1901 | 108 | 146 | ||
1902 | 109 | template<> | 147 | template<> |
1903 | 110 | void CommandLineHandler::handle<BreakpointDel>(ZORBA_TR1_NS::tuple<bint> &aTuple); | 148 | void CommandLineHandler::handle<BreakpointRemove>(ZORBA_TR1_NS::tuple<bint> &aTuple); |
1904 | 111 | 149 | ||
1905 | 112 | template<> | 150 | template<> |
1906 | 113 | void CommandLineHandler::handle<StackGet> (ZORBA_TR1_NS::tuple<bint>& aTuple); | 151 | void CommandLineHandler::handle<StackGet> (ZORBA_TR1_NS::tuple<bint>& aTuple); |
1907 | 114 | 152 | ||
1908 | 115 | template<> | 153 | template<> |
1909 | 116 | void CommandLineHandler::handle<ContextNames>(ZORBA_TR1_NS::tuple<> &aTuple); | 154 | void CommandLineHandler::handle<ContextNames>(ZORBA_TR1_NS::tuple<> &aTuple); |
1910 | 117 | 155 | ||
1911 | 118 | template<> | 156 | template<> |
1912 | 119 | void CommandLineHandler::handle<ContextGet>(ZORBA_TR1_NS::tuple<bint> &aTuple); | 157 | void CommandLineHandler::handle<ContextGet>(ZORBA_TR1_NS::tuple<bint, bint> &aTuple); |
1913 | 120 | 158 | ||
1914 | 121 | template<> | 159 | template<> |
1915 | 122 | void CommandLineHandler::handle<Eval>(ZORBA_TR1_NS::tuple<bstring>& aTuple); | 160 | void CommandLineHandler::handle<Source>(ZORBA_TR1_NS::tuple<bint, bint, bstring> &aTuple); |
1916 | 123 | 161 | ||
1917 | 124 | }} // close namespaces zorba::debugclient | 162 | template<> |
1918 | 163 | void CommandLineHandler::handle<Eval>(ZORBA_TR1_NS::tuple<bstring>& aTuple); | ||
1919 | 164 | |||
1920 | 165 | template<> | ||
1921 | 166 | void CommandLineHandler::handle<StepIn> (ZORBA_TR1_NS::tuple<> &t); | ||
1922 | 167 | |||
1923 | 168 | template<> | ||
1924 | 169 | void CommandLineHandler::handle<StepOut> (ZORBA_TR1_NS::tuple<> &t); | ||
1925 | 170 | |||
1926 | 171 | template<> | ||
1927 | 172 | void CommandLineHandler::handle<StepOver> (ZORBA_TR1_NS::tuple<> &t); | ||
1928 | 173 | |||
1929 | 174 | } // namespace zorba | ||
1930 | 175 | } // namespace debugger | ||
1931 | 176 | |||
1932 | 177 | #endif // ZORBA_DEBUGGER_COMMAND_LINE_HANDLER_H | ||
1933 | 125 | 178 | ||
1934 | === added file 'bin/debugger/command_prompt.cpp' | |||
1935 | --- bin/debugger/command_prompt.cpp 1970-01-01 00:00:00 +0000 | |||
1936 | +++ bin/debugger/command_prompt.cpp 2011-12-20 18:15:30 +0000 | |||
1937 | @@ -0,0 +1,246 @@ | |||
1938 | 1 | /* | ||
1939 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
1940 | 3 | * | ||
1941 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
1942 | 5 | * you may not use this file except in compliance with the License. | ||
1943 | 6 | * You may obtain a copy of the License at | ||
1944 | 7 | * | ||
1945 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
1946 | 9 | * | ||
1947 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
1948 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
1949 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
1950 | 13 | * See the License for the specific language governing permissions and | ||
1951 | 14 | * limitations under the License. | ||
1952 | 15 | */ | ||
1953 | 16 | #include "command_prompt.h" | ||
1954 | 17 | |||
1955 | 18 | #include <string> | ||
1956 | 19 | #include <vector> | ||
1957 | 20 | #include <map> | ||
1958 | 21 | #include <iostream> | ||
1959 | 22 | |||
1960 | 23 | #include "config.h" | ||
1961 | 24 | |||
1962 | 25 | #ifdef ZORBA_HAVE_READLINE_H | ||
1963 | 26 | # include <editline/readline.h> | ||
1964 | 27 | #endif | ||
1965 | 28 | |||
1966 | 29 | #include "command.h" | ||
1967 | 30 | |||
1968 | 31 | |||
1969 | 32 | namespace zorba { namespace debugger { | ||
1970 | 33 | |||
1971 | 34 | CommandPrompt::~CommandPrompt() | ||
1972 | 35 | { | ||
1973 | 36 | std::map<std::string, UntypedCommand*>::iterator lIter; | ||
1974 | 37 | for (lIter = theCommands.begin(); lIter != theCommands.end(); ++lIter) { | ||
1975 | 38 | delete lIter->second; | ||
1976 | 39 | } | ||
1977 | 40 | } | ||
1978 | 41 | |||
1979 | 42 | void | ||
1980 | 43 | CommandPrompt::printHelp(UntypedCommand* aCommand) | ||
1981 | 44 | { | ||
1982 | 45 | // if no command is provided, print all the available commands | ||
1983 | 46 | if (!aCommand) { | ||
1984 | 47 | std::cout << "Available commands:" << std::endl; | ||
1985 | 48 | |||
1986 | 49 | // print the names of all commands | ||
1987 | 50 | std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.begin(); | ||
1988 | 51 | while (lIter != theCommands.end()) { | ||
1989 | 52 | std::cout << " " << (*lIter).first; | ||
1990 | 53 | std::set<std::string> lAliases = (*lIter).second->getAliases(); | ||
1991 | 54 | std::set<std::string>::const_iterator lAliasIter = lAliases.begin(); | ||
1992 | 55 | while (lAliasIter != lAliases.end()) { | ||
1993 | 56 | std::cout << ", " << *lAliasIter; | ||
1994 | 57 | lAliasIter++; | ||
1995 | 58 | } | ||
1996 | 59 | std::cout << std::endl; | ||
1997 | 60 | lIter++; | ||
1998 | 61 | } | ||
1999 | 62 | |||
2000 | 63 | // some hints for detailed help | ||
2001 | 64 | std::cout << std::endl; | ||
2002 | 65 | std::cout << "Type help <command> to get more information about one command." << std::endl; | ||
2003 | 66 | std::cout << std::endl; | ||
2004 | 67 | } else { | ||
2005 | 68 | // ok, so we have a command; then print the help | ||
2006 | 69 | aCommand->printHelp(); | ||
2007 | 70 | } | ||
2008 | 71 | } | ||
2009 | 72 | |||
2010 | 73 | void | ||
2011 | 74 | CommandPrompt::execute() | ||
2012 | 75 | { | ||
2013 | 76 | for (;;) { | ||
2014 | 77 | #ifdef ZORBA_HAVE_READLINE_H | ||
2015 | 78 | std::string lCommandLine(readline("(xqdb) ")); | ||
2016 | 79 | #else | ||
2017 | 80 | std::cout << "(xqdb) "; | ||
2018 | 81 | std::string lCommandLine; | ||
2019 | 82 | std::getline(std::cin, lCommandLine); | ||
2020 | 83 | #endif | ||
2021 | 84 | std::vector<std::string> lArgs; | ||
2022 | 85 | |||
2023 | 86 | // split the command into arguments | ||
2024 | 87 | parseLine(lCommandLine, lArgs); | ||
2025 | 88 | std::string::size_type lSize = lArgs.size(); | ||
2026 | 89 | |||
2027 | 90 | // empty command? do nothing! | ||
2028 | 91 | if (lSize == 0) { | ||
2029 | 92 | lArgs = theLastArgs; | ||
2030 | 93 | if (lArgs.size() == 0) { | ||
2031 | 94 | continue; | ||
2032 | 95 | } | ||
2033 | 96 | } | ||
2034 | 97 | theLastArgs = lArgs; | ||
2035 | 98 | |||
2036 | 99 | UntypedCommand* lCommand = NULL; | ||
2037 | 100 | |||
2038 | 101 | // help is not a command but a hook here | ||
2039 | 102 | if (lArgs.at(0) == "h" || lArgs.at(0) == "help") { | ||
2040 | 103 | std::string lCmd = ""; | ||
2041 | 104 | |||
2042 | 105 | // if the user needs the help for a specific command | ||
2043 | 106 | if (lSize > 1) { | ||
2044 | 107 | // do nothing if we don't have a command starting with this prefix? | ||
2045 | 108 | // findCommand will print the appropriate errors | ||
2046 | 109 | if (!findCommand(lArgs[1], lCommand)) { | ||
2047 | 110 | continue; | ||
2048 | 111 | } | ||
2049 | 112 | } | ||
2050 | 113 | printHelp(lCommand); | ||
2051 | 114 | continue; | ||
2052 | 115 | } | ||
2053 | 116 | if (findCommand(lArgs[0], lCommand) && lCommand->execute(lArgs)) { | ||
2054 | 117 | return; | ||
2055 | 118 | } | ||
2056 | 119 | continue; | ||
2057 | 120 | } | ||
2058 | 121 | } | ||
2059 | 122 | |||
2060 | 123 | CommandPrompt& | ||
2061 | 124 | CommandPrompt::operator<<(UntypedCommand *aCommand) | ||
2062 | 125 | { | ||
2063 | 126 | theCommands.insert(std::make_pair(aCommand->getName(), aCommand)); | ||
2064 | 127 | return *this; | ||
2065 | 128 | } | ||
2066 | 129 | |||
2067 | 130 | bool | ||
2068 | 131 | CommandPrompt::findCommand(const std::string& aPrefix, UntypedCommand*& aCommand) | ||
2069 | 132 | { | ||
2070 | 133 | std::vector<UntypedCommand*> lFoundCommands; | ||
2071 | 134 | |||
2072 | 135 | std::map<std::string, UntypedCommand*>::iterator lIter = theCommands.begin(); | ||
2073 | 136 | while (lIter != theCommands.end()) { | ||
2074 | 137 | // if a command name is equal with the prefix, this is the command we want | ||
2075 | 138 | if ((*lIter).first == aPrefix) { | ||
2076 | 139 | aCommand = (*lIter).second; | ||
2077 | 140 | return true; | ||
2078 | 141 | } | ||
2079 | 142 | |||
2080 | 143 | bool lIsCandidate = false; | ||
2081 | 144 | |||
2082 | 145 | // add this command to candidate commands if the prefix matches | ||
2083 | 146 | if ((*lIter).first.find(aPrefix) == 0) { | ||
2084 | 147 | lFoundCommands.push_back((*lIter).second); | ||
2085 | 148 | lIsCandidate = true; | ||
2086 | 149 | } | ||
2087 | 150 | |||
2088 | 151 | // now process the aliases | ||
2089 | 152 | std::set<std::string> lAliases = (*lIter).second->getAliases(); | ||
2090 | 153 | std::set<std::string>::const_iterator lAliasIter = lAliases.begin(); | ||
2091 | 154 | while (lAliasIter != lAliases.end()) { | ||
2092 | 155 | // if a command alias is equal with the prefix, this is the command we want | ||
2093 | 156 | if (*lAliasIter == aPrefix) { | ||
2094 | 157 | aCommand = (*lIter).second; | ||
2095 | 158 | return true; | ||
2096 | 159 | } | ||
2097 | 160 | |||
2098 | 161 | // add this command to candidate commands if the prefix matches one alias | ||
2099 | 162 | // and if the command is not already added | ||
2100 | 163 | if (!lIsCandidate && (*lAliasIter).find(aPrefix) == 0) { | ||
2101 | 164 | lFoundCommands.push_back((*lIter).second); | ||
2102 | 165 | break; | ||
2103 | 166 | } | ||
2104 | 167 | lAliasIter++; | ||
2105 | 168 | } | ||
2106 | 169 | |||
2107 | 170 | lIter++; | ||
2108 | 171 | } | ||
2109 | 172 | |||
2110 | 173 | if (lFoundCommands.empty()) { | ||
2111 | 174 | std::cout << "Command not found: " << aPrefix << std::endl; | ||
2112 | 175 | return false; | ||
2113 | 176 | } | ||
2114 | 177 | |||
2115 | 178 | if (lFoundCommands.size() > 1) { | ||
2116 | 179 | std::cout << "Ambigous command: " << aPrefix << std::endl; | ||
2117 | 180 | // show all possible commands that start with this prefix | ||
2118 | 181 | for (std::string::size_type i = 0; i < lFoundCommands.size(); i++) { | ||
2119 | 182 | UntypedCommand* lCommand = lFoundCommands.at(i); | ||
2120 | 183 | |||
2121 | 184 | // commands | ||
2122 | 185 | if (lCommand->getName().find(aPrefix) == 0) { | ||
2123 | 186 | std::cout << " " << lCommand->getName() << std::endl; | ||
2124 | 187 | } | ||
2125 | 188 | |||
2126 | 189 | // and aliases | ||
2127 | 190 | std::set<std::string> lAliases = lCommand->getAliases(); | ||
2128 | 191 | std::set<std::string>::const_iterator lAliasIter = lAliases.begin(); | ||
2129 | 192 | while (lAliasIter != lAliases.end()) { | ||
2130 | 193 | if ((*lAliasIter).find(aPrefix) == 0) { | ||
2131 | 194 | std::cout << " " << *lAliasIter << std::endl; | ||
2132 | 195 | } | ||
2133 | 196 | lAliasIter++; | ||
2134 | 197 | } | ||
2135 | 198 | } | ||
2136 | 199 | return false; | ||
2137 | 200 | } | ||
2138 | 201 | |||
2139 | 202 | aCommand = lFoundCommands[0]; | ||
2140 | 203 | return true; | ||
2141 | 204 | } | ||
2142 | 205 | |||
2143 | 206 | void | ||
2144 | 207 | CommandPrompt::parseLine(const std::string& aLine, std::vector<std::string>& aVector) | ||
2145 | 208 | { | ||
2146 | 209 | std::string::size_type lBefore = 0; | ||
2147 | 210 | std::string::size_type lPos = aLine.find_first_of(" \t", 0); | ||
2148 | 211 | |||
2149 | 212 | while (lPos != aLine.npos) { | ||
2150 | 213 | std::string lSub = aLine.substr(lBefore, lPos - lBefore); | ||
2151 | 214 | |||
2152 | 215 | // if two consecutive spaces, you get an empty string here | ||
2153 | 216 | if (lSub != "") { | ||
2154 | 217 | if (lSub[0] == '"') { | ||
2155 | 218 | std::string::size_type lBeforeCopy = lBefore; | ||
2156 | 219 | do { | ||
2157 | 220 | lBeforeCopy = aLine.find("\"", lBeforeCopy + 1); | ||
2158 | 221 | } while (lPos != aLine.npos && aLine.size() > lPos + 1 && aLine[lPos + 1] == '\\'); | ||
2159 | 222 | lPos = lBeforeCopy; | ||
2160 | 223 | lSub = aLine.substr(lBefore + 1, lPos - lBefore - 1); | ||
2161 | 224 | } | ||
2162 | 225 | aVector.push_back(lSub); | ||
2163 | 226 | } | ||
2164 | 227 | |||
2165 | 228 | lBefore = lPos + 1; | ||
2166 | 229 | lPos = aLine.find_first_of(" \t", lBefore); | ||
2167 | 230 | } | ||
2168 | 231 | std::string lSub = aLine.substr(lBefore); | ||
2169 | 232 | |||
2170 | 233 | // catching the case when the command ends with a space | ||
2171 | 234 | if (lSub == "") { | ||
2172 | 235 | return; | ||
2173 | 236 | } | ||
2174 | 237 | |||
2175 | 238 | if (lSub[0] == '"') { | ||
2176 | 239 | lPos = aLine.find("\"", lBefore + 1); | ||
2177 | 240 | lSub = aLine.substr(lBefore + 1, lPos - lBefore - 1); | ||
2178 | 241 | } | ||
2179 | 242 | aVector.push_back(lSub); | ||
2180 | 243 | } | ||
2181 | 244 | |||
2182 | 245 | } // namespace zorba | ||
2183 | 246 | } // namespace debugger | ||
2184 | 0 | 247 | ||
2185 | === added file 'bin/debugger/command_prompt.h' | |||
2186 | --- bin/debugger/command_prompt.h 1970-01-01 00:00:00 +0000 | |||
2187 | +++ bin/debugger/command_prompt.h 2011-12-20 18:15:30 +0000 | |||
2188 | @@ -0,0 +1,60 @@ | |||
2189 | 1 | /* | ||
2190 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
2191 | 3 | * | ||
2192 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
2193 | 5 | * you may not use this file except in compliance with the License. | ||
2194 | 6 | * You may obtain a copy of the License at | ||
2195 | 7 | * | ||
2196 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
2197 | 9 | * | ||
2198 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
2199 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
2200 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
2201 | 13 | * See the License for the specific language governing permissions and | ||
2202 | 14 | * limitations under the License. | ||
2203 | 15 | */ | ||
2204 | 16 | #pragma once | ||
2205 | 17 | #ifndef ZORBA_DEBUGGER_COMMAND_PROMPT_H | ||
2206 | 18 | #define ZORBA_DEBUGGER_COMMAND_PROMPT_H | ||
2207 | 19 | |||
2208 | 20 | #include <string> | ||
2209 | 21 | #include <map> | ||
2210 | 22 | #include <vector> | ||
2211 | 23 | |||
2212 | 24 | |||
2213 | 25 | namespace zorba { namespace debugger { | ||
2214 | 26 | |||
2215 | 27 | class UntypedCommand; | ||
2216 | 28 | |||
2217 | 29 | class CommandPrompt | ||
2218 | 30 | { | ||
2219 | 31 | public: | ||
2220 | 32 | ~CommandPrompt(); | ||
2221 | 33 | |||
2222 | 34 | public: | ||
2223 | 35 | |||
2224 | 36 | void execute(); | ||
2225 | 37 | |||
2226 | 38 | CommandPrompt& operator<< (UntypedCommand* command); | ||
2227 | 39 | |||
2228 | 40 | private: | ||
2229 | 41 | |||
2230 | 42 | void | ||
2231 | 43 | printHelp(UntypedCommand* command); | ||
2232 | 44 | |||
2233 | 45 | bool | ||
2234 | 46 | findCommand(const std::string& prefix, UntypedCommand*& command); | ||
2235 | 47 | |||
2236 | 48 | void | ||
2237 | 49 | parseLine(const std::string& line, std::vector<std::string>& vector); | ||
2238 | 50 | |||
2239 | 51 | private: | ||
2240 | 52 | std::map<std::string, UntypedCommand*> theCommands; | ||
2241 | 53 | std::vector<std::string> theLastArgs; | ||
2242 | 54 | }; | ||
2243 | 55 | |||
2244 | 56 | |||
2245 | 57 | } // namespace zorba | ||
2246 | 58 | } // namespace debugger | ||
2247 | 59 | |||
2248 | 60 | #endif // ZORBA_DEBUGGER_COMMAND_PROMPT_H | ||
2249 | 0 | 61 | ||
2250 | === added file 'bin/debugger/config.h.cmake' | |||
2251 | --- bin/debugger/config.h.cmake 1970-01-01 00:00:00 +0000 | |||
2252 | +++ bin/debugger/config.h.cmake 2011-12-20 18:15:30 +0000 | |||
2253 | @@ -0,0 +1,24 @@ | |||
2254 | 1 | /* | ||
2255 | 2 | * Copyright 2006-2008 The FLWOR Foundation. | ||
2256 | 3 | * | ||
2257 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
2258 | 5 | * you may not use this file except in compliance with the License. | ||
2259 | 6 | * You may obtain a copy of the License at | ||
2260 | 7 | * | ||
2261 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
2262 | 9 | * | ||
2263 | 10 | * Unless required by applicable law or agreed to in writing, software | ||
2264 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
2265 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
2266 | 13 | * See the License for the specific language governing permissions and | ||
2267 | 14 | * limitations under the License. | ||
2268 | 15 | */ | ||
2269 | 16 | |||
2270 | 17 | // This header is configured by Zorba's build process -- DO NOT EDIT! | ||
2271 | 18 | |||
2272 | 19 | #ifndef ZORBA_DEBUGGER_CONFIG_H | ||
2273 | 20 | #define ZORBA_DEBUGGER_CONFIG_H | ||
2274 | 21 | |||
2275 | 22 | #cmakedefine ZORBA_HAVE_READLINE_H | ||
2276 | 23 | |||
2277 | 24 | #endif /* ZORBA_DEBUGGER_CONFIG_H */ | ||
2278 | 0 | 25 | ||
2279 | === modified file 'bin/debugger/event_handler.cpp' | |||
2280 | --- bin/debug_client/event_handler.cpp 2011-07-01 01:53:24 +0000 | |||
2281 | +++ bin/debugger/event_handler.cpp 2011-12-20 18:15:30 +0000 | |||
2282 | @@ -13,88 +13,94 @@ | |||
2283 | 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
2284 | 14 | * limitations under the License. | 14 | * limitations under the License. |
2285 | 15 | */ | 15 | */ |
2286 | 16 | |||
2287 | 17 | #include "event_handler.h" | ||
2288 | 18 | |||
2289 | 19 | #include <sstream> | ||
2290 | 20 | |||
2291 | 16 | #include <zorba/zorba.h> | 21 | #include <zorba/zorba.h> |
2292 | 17 | #include <zorba/store_manager.h> | 22 | #include <zorba/store_manager.h> |
2293 | 18 | #include <zorba/iterator.h> | 23 | #include <zorba/iterator.h> |
2294 | 19 | #include <sstream> | ||
2295 | 20 | #include "debug_client/event_handler.h" | ||
2296 | 21 | 24 | ||
2298 | 22 | namespace zorba { namespace debugclient { | 25 | namespace zorba { namespace debugger { |
2299 | 23 | 26 | ||
2301 | 24 | EventHandler::EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContProducer) | 27 | EventHandler::EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContProducer) |
2302 | 25 | : theIdQueue(aQueue), theContinueProducer(aContProducer), | 28 | : theIdQueue(aQueue), theContinueProducer(aContProducer), |
2303 | 26 | theStore(StoreManager::getStore()), | 29 | theStore(StoreManager::getStore()), |
2304 | 27 | theZorbaInstance(Zorba::getInstance(theStore)), | 30 | theZorbaInstance(Zorba::getInstance(theStore)), |
2305 | 28 | theStaticContext(theZorbaInstance->createStaticContext()) | 31 | theStaticContext(theZorbaInstance->createStaticContext()) |
2378 | 29 | 32 | { | |
2379 | 30 | { | 33 | } |
2380 | 31 | try { | 34 | |
2381 | 32 | Zorba_CompilerHints_t lHints; | 35 | EventHandler::~EventHandler() |
2382 | 33 | lHints.opt_level = ZORBA_OPT_LEVEL_O1; | 36 | { |
2383 | 34 | std::auto_ptr<std::istream> stream(getCurrentDirectory()); | 37 | theStaticContext = 0; |
2384 | 35 | zorba::String query; | 38 | theZorbaInstance->shutdown(); |
2385 | 36 | char buffer[1024]; | 39 | StoreManager::shutdownStore(theStore); |
2386 | 37 | std::string::size_type s; | 40 | } |
2387 | 38 | while ((s = stream->readsome(buffer, 1024))) { | 41 | |
2388 | 39 | query.append(std::string(buffer, s)); | 42 | void |
2389 | 40 | } | 43 | EventHandler::init() |
2390 | 41 | theStaticContext->loadProlog(query, lHints); | 44 | { |
2391 | 42 | } catch (zorba::ZorbaException& e) { | 45 | try { |
2392 | 43 | std::cerr << "Exception: I was not able to load the query file:" << std::endl; | 46 | Zorba_CompilerHints_t lHints; |
2393 | 44 | std::cerr << e.what() << std::endl; | 47 | lHints.opt_level = ZORBA_OPT_LEVEL_O1; |
2394 | 45 | throw; | 48 | zorba::String lProlog("import module namespace dmh = 'http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler';"); |
2395 | 46 | } | 49 | theStaticContext->loadProlog(lProlog, lHints); |
2396 | 47 | } | 50 | } catch (zorba::ZorbaException& e) { |
2397 | 48 | 51 | std::cerr << "Exception: I was not able to load the query file:" << std::endl; | |
2398 | 49 | EventHandler::~EventHandler() | 52 | std::cerr << e.what() << std::endl; |
2399 | 50 | { | 53 | throw; |
2400 | 51 | theStaticContext = 0; | 54 | } |
2401 | 52 | theZorbaInstance->shutdown(); | 55 | } |
2402 | 53 | StoreManager::shutdownStore(theStore); | 56 | |
2403 | 54 | } | 57 | void |
2404 | 55 | 58 | EventHandler::parseMessage(const std::string &aMessage) | |
2405 | 56 | void EventHandler::parseMessage(const std::string &aMessage) | 59 | { |
2406 | 57 | { | 60 | try { |
2407 | 58 | try { | 61 | #ifndef NDEBUG |
2408 | 59 | zorba::String queryString = "local:main("; | 62 | // uncomment this to see the raw messages received by the event handler |
2409 | 60 | queryString += aMessage + ")"; | 63 | //std::cout << "Processing response: " << aMessage << std::endl; |
2410 | 61 | XQuery_t query = theZorbaInstance->compileQuery(queryString, theStaticContext); | 64 | #endif |
2411 | 62 | Iterator_t lIter = query->iterator(); | 65 | // the query to process the response |
2412 | 63 | Item item; | 66 | std::stringstream lQueryStream; |
2413 | 64 | lIter->open(); | 67 | lQueryStream << "dmh:process(" << aMessage << ")"; |
2414 | 65 | bool doContinue = false; | 68 | XQuery_t lQuery = theZorbaInstance->compileQuery(lQueryStream.str(), theStaticContext); |
2415 | 66 | lIter->next(item); | 69 | |
2416 | 67 | { | 70 | // get the query result sequrence: |
2417 | 68 | const std::string& continueString = item.getStringValue().str(); | 71 | // 1. a message |
2418 | 69 | if (continueString == "true") { | 72 | Iterator_t lIter = lQuery->iterator(); |
2419 | 70 | doContinue = true; | 73 | Item lItem; |
2420 | 71 | } else if (continueString == "false") { | 74 | lIter->open(); |
2421 | 72 | doContinue = false; | 75 | lIter->next(lItem); |
2422 | 73 | } else { | 76 | std::size_t lId; |
2423 | 74 | std::stringstream stream(continueString); | 77 | std::stringstream lStream(lItem.getStringValue().c_str()); |
2424 | 75 | stream >> doContinue; | 78 | lStream >> lId; |
2425 | 76 | } | 79 | |
2426 | 77 | } | 80 | // 2. an "idle" flag (to disable quit confirmation) |
2427 | 78 | lIter->next(item); | 81 | bool lCanQuit = false; |
2428 | 79 | std::size_t lId; | 82 | if (lIter->next(lItem)) { |
2429 | 80 | { | 83 | String lMessage = lItem.getStringValue(); |
2430 | 81 | std::stringstream stream(item.getStringValue().c_str()); | 84 | lCanQuit = lMessage == "idle"; |
2431 | 82 | stream >> lId; | 85 | std::cout << std::endl << lItem.getStringValue() << std::endl; |
2432 | 83 | } | 86 | } |
2433 | 84 | lIter->next(item); | 87 | theContinueProducer.produce(lCanQuit); |
2434 | 85 | std::cout << item.getStringValue() << std::endl; | 88 | |
2435 | 86 | theContinueProducer.produce(doContinue); | 89 | // go and solve the event with this id |
2436 | 87 | theIdQueue.produce(lId); | 90 | theIdQueue.produce(lId); |
2437 | 88 | } catch (ZorbaException& e) { | 91 | } catch (ZorbaException& e) { |
2438 | 89 | std::cerr << "FATAL: could not execute query: " << std::endl; | 92 | std::cerr << "FATAL: could not execute query: " << std::endl; |
2439 | 90 | std::cerr << e << std::endl; | 93 | std::cerr << e << std::endl; |
2440 | 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; |
2441 | 92 | theContinueProducer.produce(false); | 95 | //theContinueProducer.produce(false); |
2442 | 93 | } | 96 | } |
2443 | 94 | } | 97 | } |
2444 | 95 | 98 | ||
2445 | 96 | void EventHandler::error(unsigned int errcode, const std::string &msg) | 99 | void |
2446 | 97 | { | 100 | EventHandler::error(unsigned int errcode, const std::string &msg) |
2447 | 98 | std::cerr << "Error " << errcode << ": " << msg << std::endl; | 101 | { |
2448 | 99 | } | 102 | std::cerr << "Error " << errcode << ": " << msg << std::endl; |
2449 | 100 | }} | 103 | } |
2450 | 104 | |||
2451 | 105 | } // namespace zorba | ||
2452 | 106 | } // namespace debugger | ||
2453 | 101 | 107 | ||
2454 | === modified file 'bin/debugger/event_handler.h' | |||
2455 | --- bin/debug_client/event_handler.h 2011-07-01 01:53:24 +0000 | |||
2456 | +++ bin/debugger/event_handler.h 2011-12-20 18:15:30 +0000 | |||
2457 | @@ -14,33 +14,46 @@ | |||
2458 | 14 | * limitations under the License. | 14 | * limitations under the License. |
2459 | 15 | */ | 15 | */ |
2460 | 16 | #pragma once | 16 | #pragma once |
2461 | 17 | #ifndef ZORBA_DEBUGGER_EVENT_HANDLER_H | ||
2462 | 18 | #define ZORBA_DEBUGGER_EVENT_HANDLER_H | ||
2463 | 19 | |||
2464 | 17 | #include <string> | 20 | #include <string> |
2465 | 18 | #include <iostream> | 21 | #include <iostream> |
2466 | 22 | |||
2467 | 19 | #include <zorba/debugger_event_handler.h> | 23 | #include <zorba/debugger_event_handler.h> |
2468 | 20 | #include <zorba/static_context.h> | 24 | #include <zorba/static_context.h> |
2469 | 25 | |||
2470 | 21 | #include "lock_free_queue.h" | 26 | #include "lock_free_queue.h" |
2471 | 22 | 27 | ||
2480 | 23 | namespace zorba { | 28 | |
2481 | 24 | class Zorba; | 29 | namespace zorba { namespace debugger { |
2482 | 25 | } | 30 | |
2483 | 26 | 31 | class EventHandler : public zorba::DebuggerEventHandler | |
2484 | 27 | namespace zorba { namespace debugclient { | 32 | { |
2477 | 28 | |||
2478 | 29 | class EventHandler : public zorba::DebuggerEventHandler | ||
2479 | 30 | { | ||
2485 | 31 | public: | 33 | public: |
2487 | 32 | EventHandler(LockFreeProducer<std::size_t>& aQueue, LockFreeProducer<bool>& aContQueue); | 34 | EventHandler( |
2488 | 35 | LockFreeProducer<std::size_t>& aQueue, | ||
2489 | 36 | LockFreeProducer<bool>& aContQueue); | ||
2490 | 37 | |||
2491 | 33 | ~EventHandler(); | 38 | ~EventHandler(); |
2492 | 39 | |||
2493 | 34 | public: | 40 | public: |
2494 | 35 | virtual void parseMessage(const std::string& aMessage); | 41 | virtual void parseMessage(const std::string& aMessage); |
2495 | 42 | |||
2496 | 36 | virtual void error(unsigned int errcode, const std::string& msg); | 43 | virtual void error(unsigned int errcode, const std::string& msg); |
2497 | 44 | |||
2498 | 45 | virtual void init(); | ||
2499 | 46 | |||
2500 | 37 | private: | 47 | private: |
2501 | 38 | static std::istream* getCurrentDirectory(); | ||
2502 | 39 | LockFreeProducer<std::size_t>& theIdQueue; | 48 | LockFreeProducer<std::size_t>& theIdQueue; |
2503 | 40 | LockFreeProducer<bool>& theContinueProducer; | 49 | LockFreeProducer<bool>& theContinueProducer; |
2504 | 41 | void* theStore; | 50 | void* theStore; |
2505 | 42 | Zorba* theZorbaInstance; | 51 | Zorba* theZorbaInstance; |
2506 | 43 | StaticContext_t theStaticContext; | 52 | StaticContext_t theStaticContext; |
2508 | 44 | }; | 53 | |
2509 | 54 | }; | ||
2510 | 45 | 55 | ||
2512 | 46 | }} // end of namespace zorba::debugclient | 56 | } // namespace zorba |
2513 | 57 | } // namespace debugger | ||
2514 | 58 | |||
2515 | 59 | #endif // ZORBA_DEBUGGER_EVENT_HANDLER_H | ||
2516 | 47 | 60 | ||
2517 | === modified file 'bin/debugger/lock_free_queue.h' | |||
2518 | --- bin/debug_client/lock_free_queue.h 2011-07-01 01:53:24 +0000 | |||
2519 | +++ bin/debugger/lock_free_queue.h 2011-12-20 18:15:30 +0000 | |||
2520 | @@ -14,10 +14,14 @@ | |||
2521 | 14 | * limitations under the License. | 14 | * limitations under the License. |
2522 | 15 | */ | 15 | */ |
2523 | 16 | #pragma once | 16 | #pragma once |
2524 | 17 | #ifndef ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H | ||
2525 | 18 | #define ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H | ||
2526 | 19 | |||
2527 | 17 | #include <iostream> | 20 | #include <iostream> |
2528 | 18 | #include <list> | 21 | #include <list> |
2529 | 19 | 22 | ||
2531 | 20 | namespace zorba { namespace debugclient { | 23 | |
2532 | 24 | namespace zorba { namespace debugger { | ||
2533 | 21 | 25 | ||
2534 | 22 | template<typename T> | 26 | template<typename T> |
2535 | 23 | class LockFreeProducer | 27 | class LockFreeProducer |
2536 | @@ -80,4 +84,8 @@ | |||
2537 | 80 | } | 84 | } |
2538 | 81 | return false; | 85 | return false; |
2539 | 82 | } | 86 | } |
2541 | 83 | }} // namespace zorba::debugclient | 87 | |
2542 | 88 | } // namespace zorba | ||
2543 | 89 | } // namespace debugger | ||
2544 | 90 | |||
2545 | 91 | #endif // ZORBA_DEBUGGER_LOCK_FREE_QUEUE_H | ||
2546 | 84 | 92 | ||
2547 | === modified file 'bin/debugger/main.cpp' | |||
2548 | --- bin/debug_client/main.cpp 2011-07-01 01:53:24 +0000 | |||
2549 | +++ bin/debugger/main.cpp 2011-12-20 18:15:30 +0000 | |||
2550 | @@ -13,12 +13,244 @@ | |||
2551 | 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
2552 | 14 | * limitations under the License. | 14 | * limitations under the License. |
2553 | 15 | */ | 15 | */ |
2554 | 16 | |||
2555 | 17 | #ifdef WIN32 | ||
2556 | 18 | # include <windows.h> | ||
2557 | 19 | # include <string.h> | ||
2558 | 20 | # include <strsafe.h> | ||
2559 | 21 | #endif | ||
2560 | 22 | |||
2561 | 23 | #include <vector> | ||
2562 | 24 | |||
2563 | 16 | #include <zorba/config.h> | 25 | #include <zorba/config.h> |
2565 | 17 | #include "debug_command.h" | 26 | |
2566 | 27 | #include "command_prompt.h" | ||
2567 | 18 | #include "command_line_handler.h" | 28 | #include "command_line_handler.h" |
2568 | 19 | 29 | ||
2569 | 20 | using namespace zorba; | 30 | using namespace zorba; |
2571 | 21 | using namespace zorba::debugclient; | 31 | using namespace zorba::debugger; |
2572 | 32 | |||
2573 | 33 | int | ||
2574 | 34 | startZorba(std::string& aExec, std::vector<std::string>& aArgs) | ||
2575 | 35 | { | ||
2576 | 36 | #ifdef WIN32 | ||
2577 | 37 | // ************************** | ||
2578 | 38 | // start a process on Windows | ||
2579 | 39 | |||
2580 | 40 | DWORD iReturnVal = 0; | ||
2581 | 41 | DWORD dwExitCode = 0; | ||
2582 | 42 | |||
2583 | 43 | std::wstring lExec; | ||
2584 | 44 | std::wstring lArgs; | ||
2585 | 45 | |||
2586 | 46 | lExec.assign(aExec.begin(), aExec.end()); | ||
2587 | 47 | |||
2588 | 48 | // the executable must be the first in the list of arguments | ||
2589 | 49 | lArgs.append(L"\""); | ||
2590 | 50 | lArgs.append(lExec); | ||
2591 | 51 | lArgs.append(L"\""); | ||
2592 | 52 | |||
2593 | 53 | for (std::vector<std::string>::size_type j = 0; j < aArgs.size(); j++) { | ||
2594 | 54 | std::string lArg(aArgs.at(j)); | ||
2595 | 55 | std::wstring lArgW; | ||
2596 | 56 | lArgW.assign(lArg.begin(), lArg.end()); | ||
2597 | 57 | lArgs.append(L" "); | ||
2598 | 58 | lArgs.append(lArgW); | ||
2599 | 59 | } | ||
2600 | 60 | |||
2601 | 61 | // CreateProcessW can modify Parameters thus we allocate needed memory | ||
2602 | 62 | wchar_t * pwszParam = new wchar_t[lArgs.size() + 1]; | ||
2603 | 63 | if (pwszParam == 0) { | ||
2604 | 64 | return 1; | ||
2605 | 65 | } | ||
2606 | 66 | const wchar_t* pchrTemp = lArgs.c_str(); | ||
2607 | 67 | wcscpy_s(pwszParam, lArgs.size() + 1, pchrTemp); | ||
2608 | 68 | |||
2609 | 69 | // CreateProcess API initialization | ||
2610 | 70 | STARTUPINFOW siStartupInfo; | ||
2611 | 71 | PROCESS_INFORMATION piProcessInfo; | ||
2612 | 72 | memset(&siStartupInfo, 0, sizeof(siStartupInfo)); | ||
2613 | 73 | memset(&piProcessInfo, 0, sizeof(piProcessInfo)); | ||
2614 | 74 | siStartupInfo.cb = sizeof(siStartupInfo); | ||
2615 | 75 | |||
2616 | 76 | BOOL lResult = CreateProcessW( | ||
2617 | 77 | const_cast<LPCWSTR>(lExec.c_str()), | ||
2618 | 78 | pwszParam, 0, 0, false, | ||
2619 | 79 | CREATE_DEFAULT_ERROR_MODE, 0, 0, | ||
2620 | 80 | &siStartupInfo, &piProcessInfo); | ||
2621 | 81 | |||
2622 | 82 | if (lResult) { | ||
2623 | 83 | // Watch the process | ||
2624 | 84 | dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, 0); | ||
2625 | 85 | } | ||
2626 | 86 | else { | ||
2627 | 87 | // CreateProcess failed | ||
2628 | 88 | iReturnVal = GetLastError(); | ||
2629 | 89 | LPVOID lpMsgBuf; | ||
2630 | 90 | LPVOID lpDisplayBuf; | ||
2631 | 91 | |||
2632 | 92 | FormatMessage( | ||
2633 | 93 | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | ||
2634 | 94 | NULL, | ||
2635 | 95 | iReturnVal, | ||
2636 | 96 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | ||
2637 | 97 | (LPTSTR) &lpMsgBuf, | ||
2638 | 98 | 0, NULL); | ||
2639 | 99 | |||
2640 | 100 | // Display the error message and exit the process | ||
2641 | 101 | |||
2642 | 102 | lpDisplayBuf = (LPVOID)LocalAlloc( | ||
2643 | 103 | LMEM_ZEROINIT, | ||
2644 | 104 | (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR)); | ||
2645 | 105 | |||
2646 | 106 | StringCchPrintf( | ||
2647 | 107 | (LPTSTR)lpDisplayBuf, | ||
2648 | 108 | LocalSize(lpDisplayBuf) / sizeof(TCHAR), | ||
2649 | 109 | TEXT("Error (%d) when starting zorba: %s"), | ||
2650 | 110 | iReturnVal, | ||
2651 | 111 | lpMsgBuf); | ||
2652 | 112 | |||
2653 | 113 | std::wstring lErrorW((wchar_t*)lpDisplayBuf); | ||
2654 | 114 | std::string lError; | ||
2655 | 115 | lError.assign(lErrorW.begin(), lErrorW.end()); | ||
2656 | 116 | std::cout << lError << std::endl; | ||
2657 | 117 | |||
2658 | 118 | LocalFree(lpMsgBuf); | ||
2659 | 119 | LocalFree(lpDisplayBuf); | ||
2660 | 120 | } | ||
2661 | 121 | |||
2662 | 122 | // Free memory | ||
2663 | 123 | delete[]pwszParam; | ||
2664 | 124 | pwszParam = 0; | ||
2665 | 125 | |||
2666 | 126 | // Release handles | ||
2667 | 127 | CloseHandle(piProcessInfo.hProcess); | ||
2668 | 128 | CloseHandle(piProcessInfo.hThread); | ||
2669 | 129 | |||
2670 | 130 | return iReturnVal; | ||
2671 | 131 | |||
2672 | 132 | #else | ||
2673 | 133 | // ************************ | ||
2674 | 134 | // start a process on Linux | ||
2675 | 135 | |||
2676 | 136 | pid_t pID = fork(); | ||
2677 | 137 | if (pID == 0) { | ||
2678 | 138 | // Code only executed by child process | ||
2679 | 139 | std::stringstream lCommand; | ||
2680 | 140 | lCommand << aExec; | ||
2681 | 141 | for (std::vector<std::string>::size_type j = 0; j < aArgs.size(); j++) { | ||
2682 | 142 | lCommand << " " << aArgs.at(j); | ||
2683 | 143 | } | ||
2684 | 144 | |||
2685 | 145 | int lRes = system(lCommand.str().c_str()); | ||
2686 | 146 | exit(lRes); | ||
2687 | 147 | } | ||
2688 | 148 | else { | ||
2689 | 149 | // Code only executed by parent process | ||
2690 | 150 | if (pID < 0) { | ||
2691 | 151 | std::cerr << "Failed to fork Zorba" << std::endl; | ||
2692 | 152 | return pID; | ||
2693 | 153 | } else { | ||
2694 | 154 | return 0; | ||
2695 | 155 | } | ||
2696 | 156 | } | ||
2697 | 157 | #endif | ||
2698 | 158 | } | ||
2699 | 159 | |||
2700 | 160 | void printUsage(std::string& aProgram) | ||
2701 | 161 | { | ||
2702 | 162 | std::cerr << "Usage:" << std::endl | ||
2703 | 163 | << " " << aProgram << " <zorba_arguments>" << std::endl | ||
2704 | 164 | << " this will start a debugger command line and a zorba process with the given arguments" << std::endl; | ||
2705 | 165 | } | ||
2706 | 166 | |||
2707 | 167 | bool | ||
2708 | 168 | processArguments( | ||
2709 | 169 | int argc, | ||
2710 | 170 | char* argv[], | ||
2711 | 171 | std::string& aProgram, | ||
2712 | 172 | bool& aStandalone, | ||
2713 | 173 | std::string& aZorba, | ||
2714 | 174 | unsigned int& aPort, | ||
2715 | 175 | std::vector<std::string>& aZorbaArgs) | ||
2716 | 176 | { | ||
2717 | 177 | aPort = 28028; | ||
2718 | 178 | |||
2719 | 179 | // find the path to Zorba and this executable name | ||
2720 | 180 | aProgram = argv[0]; | ||
2721 | 181 | |||
2722 | 182 | #ifdef WIN32 | ||
2723 | 183 | char lSep = '\\'; | ||
2724 | 184 | #else | ||
2725 | 185 | char lSep = '/'; | ||
2726 | 186 | #endif | ||
2727 | 187 | std::string::size_type lPos = aProgram.find_last_of(lSep); | ||
2728 | 188 | |||
2729 | 189 | std::stringstream lZs; | ||
2730 | 190 | |||
2731 | 191 | if (lPos == aProgram.npos) { | ||
2732 | 192 | lZs << "." << lSep; | ||
2733 | 193 | } else { | ||
2734 | 194 | lZs << aProgram.substr(0, lPos + 1); | ||
2735 | 195 | aProgram = aProgram.substr(lPos + 1); | ||
2736 | 196 | } | ||
2737 | 197 | lZs << "zorba"; | ||
2738 | 198 | #ifdef WIN32 | ||
2739 | 199 | lZs << ".exe"; | ||
2740 | 200 | #endif | ||
2741 | 201 | aZorba = lZs.str(); | ||
2742 | 202 | |||
2743 | 203 | |||
2744 | 204 | bool lHasFileArg = false; | ||
2745 | 205 | bool lHasQueryArg = false; | ||
2746 | 206 | bool lHasQueryVal = false; | ||
2747 | 207 | |||
2748 | 208 | // find if the user asked for help or specified a specific port | ||
2749 | 209 | for (int i = 1; i < argc; i++) { | ||
2750 | 210 | std::string lArg = argv[i]; | ||
2751 | 211 | if (lArg == "-h" || lArg == "--help") { | ||
2752 | 212 | return false; | ||
2753 | 213 | } | ||
2754 | 214 | else if (lArg == "-p" || lArg == "--debug-port") { | ||
2755 | 215 | // if there is one more argument | ||
2756 | 216 | if (i < argc - 1) { | ||
2757 | 217 | // get the port value | ||
2758 | 218 | int lPort; | ||
2759 | 219 | std::stringstream lStream(argv[i + 1]); | ||
2760 | 220 | lStream >> lPort; | ||
2761 | 221 | if (!lStream.fail()) { | ||
2762 | 222 | aPort = lPort; | ||
2763 | 223 | } | ||
2764 | 224 | } | ||
2765 | 225 | } | ||
2766 | 226 | else if (lArg == "-f") { | ||
2767 | 227 | lHasFileArg = true; | ||
2768 | 228 | } | ||
2769 | 229 | else if (lArg == "-q") { | ||
2770 | 230 | lHasQueryArg = true; | ||
2771 | 231 | if (++i < argc) { | ||
2772 | 232 | lHasQueryVal = true; | ||
2773 | 233 | } | ||
2774 | 234 | } | ||
2775 | 235 | } | ||
2776 | 236 | |||
2777 | 237 | if (!lHasFileArg || !lHasQueryArg || !lHasQueryVal) { | ||
2778 | 238 | std::cout << "Not enough arguments to start Zorba." << std::endl; | ||
2779 | 239 | std::cout << "Running the standalone XQuery debugger client on port: " << aPort << std::endl; | ||
2780 | 240 | return true; | ||
2781 | 241 | } | ||
2782 | 242 | |||
2783 | 243 | // zorba will need the -d flag | ||
2784 | 244 | aZorbaArgs.push_back("-d"); | ||
2785 | 245 | |||
2786 | 246 | // gather all arguments (excepting the program name) | ||
2787 | 247 | for (int i = 1; i < argc; i++) { | ||
2788 | 248 | aZorbaArgs.push_back(argv[i]); | ||
2789 | 249 | } | ||
2790 | 250 | |||
2791 | 251 | aStandalone = false; | ||
2792 | 252 | return true; | ||
2793 | 253 | } | ||
2794 | 22 | 254 | ||
2795 | 23 | #ifndef _WIN32_WCE | 255 | #ifndef _WIN32_WCE |
2796 | 24 | int | 256 | int |
2797 | @@ -28,24 +260,68 @@ | |||
2798 | 28 | _tmain(int argc, _TCHAR* argv[]) | 260 | _tmain(int argc, _TCHAR* argv[]) |
2799 | 29 | #endif | 261 | #endif |
2800 | 30 | { | 262 | { |
2808 | 31 | int port = 28028; | 263 | // ************************************************************************** |
2809 | 32 | if (argv[1]) { | 264 | // processing arguments |
2810 | 33 | std::stringstream stream(argv[1]); | 265 | |
2811 | 34 | stream >> port; | 266 | std::string lProgram, lZorbaExec; |
2812 | 35 | if (stream.fail() || argv[2]) { | 267 | unsigned int lPort = 28028; |
2813 | 36 | std::cerr << "Unknown argument. USAGE: " << argv[0] << " [PORT]" << std::endl; | 268 | std::vector<std::string> lZorbaArgs; |
2814 | 37 | return 2; | 269 | |
2815 | 270 | bool lStandalone = true; | ||
2816 | 271 | if (!processArguments(argc, argv, lProgram, lStandalone, lZorbaExec, lPort, lZorbaArgs)) { | ||
2817 | 272 | printUsage(lProgram); | ||
2818 | 273 | return 1; | ||
2819 | 274 | } | ||
2820 | 275 | |||
2821 | 276 | #ifndef NDEBUG | ||
2822 | 277 | // ************************************************************************** | ||
2823 | 278 | // debug reporting | ||
2824 | 279 | |||
2825 | 280 | if (!lStandalone) { | ||
2826 | 281 | std::cout << "Communication port: " << lPort << std::endl; | ||
2827 | 282 | std::cout << "Zorba executable: " << lZorbaExec << std::endl; | ||
2828 | 283 | std::cout << "Zorba arguments: "; | ||
2829 | 284 | for (std::vector<std::string>::size_type j = 0; j < lZorbaArgs.size(); j++) { | ||
2830 | 285 | std::cout << lZorbaArgs.at(j) << " "; | ||
2831 | 38 | } | 286 | } |
2832 | 287 | std::cout << std::endl; | ||
2833 | 39 | } | 288 | } |
2834 | 289 | #endif | ||
2835 | 290 | |||
2836 | 40 | try { | 291 | try { |
2837 | 292 | // ************************************************************************** | ||
2838 | 293 | // start a zorba | ||
2839 | 294 | |||
2840 | 295 | if (!lStandalone) { | ||
2841 | 296 | int lResult = startZorba(lZorbaExec, lZorbaArgs); | ||
2842 | 297 | if (lResult) { | ||
2843 | 298 | return lResult; | ||
2844 | 299 | } | ||
2845 | 300 | } else { | ||
2846 | 301 | std::cout << "Waiting for an incomming Zorba connection..." << std::endl; | ||
2847 | 302 | } | ||
2848 | 303 | |||
2849 | 304 | // ************************************************************************** | ||
2850 | 305 | // start the debugger command line | ||
2851 | 306 | |||
2852 | 41 | LockFreeQueue<std::size_t> lQueue; | 307 | LockFreeQueue<std::size_t> lQueue; |
2853 | 42 | LockFreeQueue<bool> lContEvent; | 308 | LockFreeQueue<bool> lContEvent; |
2858 | 43 | EventHandler lHandler(lQueue, lContEvent); | 309 | EventHandler lEventHandler(lQueue, lContEvent); |
2859 | 44 | CommandLine cli; | 310 | lEventHandler.init(); |
2860 | 45 | CommandLineHandler handler(port, lQueue, lContEvent, lHandler, cli); | 311 | |
2861 | 46 | handler.execute(); | 312 | CommandPrompt lCommandPrompt; |
2862 | 313 | CommandLineHandler lCommandLineHandler(lPort, lQueue, lContEvent, lEventHandler, lCommandPrompt); | ||
2863 | 314 | |||
2864 | 315 | lCommandLineHandler.execute(); | ||
2865 | 316 | |||
2866 | 317 | #ifndef WIN32 | ||
2867 | 318 | wait(); | ||
2868 | 319 | #endif | ||
2869 | 320 | |||
2870 | 47 | } catch (...) { | 321 | } catch (...) { |
2872 | 48 | return 4; | 322 | return -1; |
2873 | 49 | } | 323 | } |
2874 | 324 | |||
2875 | 50 | return 0; | 325 | return 0; |
2876 | 51 | } | 326 | } |
2877 | 327 | |||
2878 | 52 | 328 | ||
2879 | === modified file 'bin/debugger/tuple.h' | |||
2880 | --- bin/debug_client/tuple.h 2011-07-04 08:05:46 +0000 | |||
2881 | +++ bin/debugger/tuple.h 2011-12-20 18:15:30 +0000 | |||
2882 | @@ -14,9 +14,15 @@ | |||
2883 | 14 | * limitations under the License. | 14 | * limitations under the License. |
2884 | 15 | */ | 15 | */ |
2885 | 16 | #pragma once | 16 | #pragma once |
2886 | 17 | #ifndef ZORBA_DEBUGGER_TUPLE_H | ||
2887 | 18 | #define ZORBA_DEBUGGER_TUPLE_H | ||
2888 | 19 | |||
2889 | 17 | #include <zorba/config.h> | 20 | #include <zorba/config.h> |
2890 | 21 | |||
2891 | 18 | #if ZORBA_TR1_IN_TR1_SUBDIRECTORY | 22 | #if ZORBA_TR1_IN_TR1_SUBDIRECTORY |
2892 | 19 | # include <tr1/tuple> | 23 | # include <tr1/tuple> |
2893 | 20 | #else | 24 | #else |
2894 | 21 | # include <tuple> | 25 | # include <tuple> |
2895 | 22 | #endif | 26 | #endif |
2896 | 27 | |||
2897 | 28 | #endif // ZORBA_DEBUGGER_TUPLE_H | ||
2898 | 23 | 29 | ||
2899 | === modified file 'bin/zorbacmd.cpp' | |||
2900 | --- bin/zorbacmd.cpp 2011-11-08 03:11:02 +0000 | |||
2901 | +++ bin/zorbacmd.cpp 2011-12-20 18:15:30 +0000 | |||
2902 | @@ -925,17 +925,15 @@ | |||
2903 | 925 | lHost = "127.0.0.1"; | 925 | lHost = "127.0.0.1"; |
2904 | 926 | } | 926 | } |
2905 | 927 | 927 | ||
2911 | 928 | if (lProperties.debug()) { | 928 | Zorba_SerializerOptions lSerOptions = |
2912 | 929 | Zorba_SerializerOptions lSerOptions = | 929 | Zorba_SerializerOptions::SerializerOptionsFromStringParams( |
2913 | 930 | Zorba_SerializerOptions::SerializerOptionsFromStringParams( | 930 | lProperties.getSerializerParameters()); |
2914 | 931 | lProperties.getSerializerParameters()); | 931 | createSerializerOptions(lSerOptions, lProperties); |
2910 | 932 | createSerializerOptions(lSerOptions, lProperties); | ||
2915 | 933 | 932 | ||
2920 | 934 | if (!lProperties.hasNoLogo() && !lProperties.debug()) { | 933 | if (!lProperties.hasNoLogo()) { |
2921 | 935 | std::cout << "Zorba XQuery Debugger Server\n" << copyright_str << std::endl; | 934 | std::cout << "Zorba XQuery Debugger Server\n" << copyright_str << std::endl; |
2918 | 936 | } | ||
2919 | 937 | lQuery->debug(*lOutputStream, lSerOptions, lHost, lProperties.getDebugPort()); | ||
2922 | 938 | } | 935 | } |
2923 | 936 | lQuery->debug(*lOutputStream, lSerOptions, lHost, lProperties.getDebugPort()); | ||
2924 | 939 | } | 937 | } |
2925 | 940 | catch (zorba::XQueryException const& qe) | 938 | catch (zorba::XQueryException const& qe) |
2926 | 941 | { | 939 | { |
2927 | 942 | 940 | ||
2928 | === added file 'cmake_modules/FindLibedit.cmake' | |||
2929 | --- cmake_modules/FindLibedit.cmake 1970-01-01 00:00:00 +0000 | |||
2930 | +++ cmake_modules/FindLibedit.cmake 2011-12-20 18:15:30 +0000 | |||
2931 | @@ -0,0 +1,46 @@ | |||
2932 | 1 | # Copyright 2011 The FLWOR Foundation. | ||
2933 | 2 | # | ||
2934 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
2935 | 4 | # you may not use this file except in compliance with the License. | ||
2936 | 5 | # You may obtain a copy of the License at | ||
2937 | 6 | # | ||
2938 | 7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
2939 | 8 | # | ||
2940 | 9 | # Unless required by applicable law or agreed to in writing, software | ||
2941 | 10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
2942 | 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
2943 | 12 | # See the License for the specific language governing permissions and | ||
2944 | 13 | # limitations under the License. | ||
2945 | 14 | # | ||
2946 | 15 | # - Try to find the libedit library | ||
2947 | 16 | # | ||
2948 | 17 | # Once done this will define | ||
2949 | 18 | # | ||
2950 | 19 | # LIBEDIT_FOUND - True if libedit library is found | ||
2951 | 20 | # LIBEDIT_INCLUDE_DIRS - Directory to include to get libedit headers | ||
2952 | 21 | # LIBEDIT_LIBRARIES - Libraries to link against for the libedit library | ||
2953 | 22 | # | ||
2954 | 23 | |||
2955 | 24 | FIND_PATH ( | ||
2956 | 25 | LIBEDIT_INCLUDE | ||
2957 | 26 | editline/readline.h | ||
2958 | 27 | PATHS ${LIBEDIT_INCLUDE_DIR} /usr/include /usr/local/include | ||
2959 | 28 | ) | ||
2960 | 29 | MESSAGE(STATUS ${LIBEDIT_INCLUDE}) | ||
2961 | 30 | |||
2962 | 31 | FIND_LIBRARY ( | ||
2963 | 32 | LIBEDIT_LIBRARY | ||
2964 | 33 | NAMES edit | ||
2965 | 34 | PATHS ${LIBEDIT_LIBRARY_DIR} /usr/lib /usr/local/lib /usr/lib64 /usr/local/lib64 | ||
2966 | 35 | ) | ||
2967 | 36 | MESSAGE(STATUS ${LIBEDIT_LIBRARY}) | ||
2968 | 37 | |||
2969 | 38 | SET (LIBEDIT_INCLUDE_DIRS ${LIBEDIT_INCLUDE}) | ||
2970 | 39 | SET (LIBEDIT_LIBRARIES ${LIBEDIT_LIBRARY}) | ||
2971 | 40 | |||
2972 | 41 | FIND_PACKAGE_HANDLE_STANDARD_ARGS ( | ||
2973 | 42 | Libedit | ||
2974 | 43 | DEFAULT_MSG | ||
2975 | 44 | LIBEDIT_INCLUDE LIBEDIT_LIBRARY | ||
2976 | 45 | ) | ||
2977 | 46 | |||
2978 | 0 | 47 | ||
2979 | === modified file 'include/zorba/config.h.cmake' | |||
2980 | --- include/zorba/config.h.cmake 2011-10-19 16:19:45 +0000 | |||
2981 | +++ include/zorba/config.h.cmake 2011-12-20 18:15:30 +0000 | |||
2982 | @@ -39,19 +39,19 @@ | |||
2983 | 39 | #endif /* WIN32 */ | 39 | #endif /* WIN32 */ |
2984 | 40 | 40 | ||
2985 | 41 | // Platform headers | 41 | // Platform headers |
2987 | 42 | #cmakedefine ZORBA_HAVE_COLL_H | 42 | #cmakedefine ZORBA_HAVE_COLL_H |
2988 | 43 | #cmakedefine ZORBA_HAVE_EXECINFO_H | 43 | #cmakedefine ZORBA_HAVE_EXECINFO_H |
2989 | 44 | #cmakedefine ZORBA_HAVE_FLEXLEXER_H | 44 | #cmakedefine ZORBA_HAVE_FLEXLEXER_H |
2990 | 45 | #cmakedefine ZORBA_HAVE_ICONV_H | 45 | #cmakedefine ZORBA_HAVE_ICONV_H |
2996 | 46 | #cmakedefine ZORBA_HAVE_INTTYPES_H | 46 | #cmakedefine ZORBA_HAVE_INTTYPES_H |
2997 | 47 | #cmakedefine ZORBA_HAVE_LIMITS_H | 47 | #cmakedefine ZORBA_HAVE_LIMITS_H |
2998 | 48 | #cmakedefine ZORBA_HAVE_PTHREAD_H | 48 | #cmakedefine ZORBA_HAVE_PTHREAD_H |
2999 | 49 | #cmakedefine ZORBA_HAVE_STDINT_H | 49 | #cmakedefine ZORBA_HAVE_STDINT_H |
3000 | 50 | #cmakedefine ZORBA_HAVE_STDLIB_H | 50 | #cmakedefine ZORBA_HAVE_STDLIB_H |
3001 | 51 | #cmakedefine ZORBA_HAVE_SYS_MOUNT_H | 51 | #cmakedefine ZORBA_HAVE_SYS_MOUNT_H |
3002 | 52 | #cmakedefine ZORBA_HAVE_SYS_TYPES_H | 52 | #cmakedefine ZORBA_HAVE_SYS_TYPES_H |
3005 | 53 | #cmakedefine ZORBA_HAVE_USTRING_H | 53 | #cmakedefine ZORBA_HAVE_USTRING_H |
3006 | 54 | #cmakedefine ZORBA_HAVE_UTYPES_H | 54 | #cmakedefine ZORBA_HAVE_UTYPES_H |
3007 | 55 | 55 | ||
3008 | 56 | // Platform functions | 56 | // Platform functions |
3009 | 57 | #cmakedefine ZORBA_HAVE_CLOCKGETTIME_FUNCTION | 57 | #cmakedefine ZORBA_HAVE_CLOCKGETTIME_FUNCTION |
3010 | 58 | 58 | ||
3011 | === modified file 'include/zorba/debugger_client.h' | |||
3012 | --- include/zorba/debugger_client.h 2011-07-24 22:28:31 +0000 | |||
3013 | +++ include/zorba/debugger_client.h 2011-12-20 18:15:30 +0000 | |||
3014 | @@ -162,6 +162,13 @@ | |||
3015 | 162 | * @return The id of the request. | 162 | * @return The id of the request. |
3016 | 163 | */ | 163 | */ |
3017 | 164 | virtual std::size_t status() = 0; | 164 | virtual std::size_t status() = 0; |
3018 | 165 | |||
3019 | 166 | /** | ||
3020 | 167 | * @brief Get the variables in all the contexts in the topmost stack frame. | ||
3021 | 168 | * | ||
3022 | 169 | * @return The id of the request. | ||
3023 | 170 | */ | ||
3024 | 171 | virtual std::size_t variables() = 0; | ||
3025 | 165 | 172 | ||
3026 | 166 | /** | 173 | /** |
3027 | 167 | * @brief Query the debug engine for supported features. | 174 | * @brief Query the debug engine for supported features. |
3028 | @@ -521,6 +528,7 @@ | |||
3029 | 521 | */ | 528 | */ |
3030 | 522 | virtual void quit() = 0; | 529 | virtual void quit() = 0; |
3031 | 523 | }; | 530 | }; |
3032 | 531 | |||
3033 | 524 | }//end of namespace | 532 | }//end of namespace |
3034 | 533 | |||
3035 | 525 | #endif | 534 | #endif |
3036 | 526 | /* vim:set et sw=2 ts=2: */ | ||
3037 | 527 | 535 | ||
3038 | === modified file 'modules/com/zorba-xquery/www/modules/CMakeLists.txt' | |||
3039 | --- modules/com/zorba-xquery/www/modules/CMakeLists.txt 2011-10-14 07:35:51 +0000 | |||
3040 | +++ modules/com/zorba-xquery/www/modules/CMakeLists.txt 2011-12-20 18:15:30 +0000 | |||
3041 | @@ -100,6 +100,13 @@ | |||
3042 | 100 | DECLARE_ZORBA_MODULE(FILE store/static/integrity_constraints/dml.xq VERSION 2.0 | 100 | DECLARE_ZORBA_MODULE(FILE store/static/integrity_constraints/dml.xq VERSION 2.0 |
3043 | 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") |
3044 | 102 | 102 | ||
3045 | 103 | # debugger client DBGP message handler module | ||
3046 | 104 | IF (ZORBA_WITH_DEBUGGER) | ||
3047 | 105 | DECLARE_ZORBA_MODULE (FILE debugger/dbgp-message-handler.xq VERSION 1.0 | ||
3048 | 106 | URI "http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler") | ||
3049 | 107 | ENDIF (ZORBA_WITH_DEBUGGER) | ||
3050 | 108 | |||
3051 | 109 | |||
3052 | 103 | # error and warning modules | 110 | # error and warning modules |
3053 | 104 | DECLARE_ZORBA_MODULE (FILE pregenerated/errors.xq | 111 | DECLARE_ZORBA_MODULE (FILE pregenerated/errors.xq |
3054 | 105 | URI "http://www.zorba-xquery.com/errors" | 112 | URI "http://www.zorba-xquery.com/errors" |
3055 | 106 | 113 | ||
3056 | === added directory 'modules/com/zorba-xquery/www/modules/debugger' | |||
3057 | === added file 'modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq' | |||
3058 | --- modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq 1970-01-01 00:00:00 +0000 | |||
3059 | +++ modules/com/zorba-xquery/www/modules/debugger/dbgp-message-handler.xq 2011-12-20 18:15:30 +0000 | |||
3060 | @@ -0,0 +1,277 @@ | |||
3061 | 1 | xquery version "3.0"; | ||
3062 | 2 | |||
3063 | 3 | (: | ||
3064 | 4 | : Copyright 2006-2009 The FLWOR Foundation. | ||
3065 | 5 | : | ||
3066 | 6 | : Licensed under the Apache License, Version 2.0 (the "License"); | ||
3067 | 7 | : you may not use this file except in compliance with the License. | ||
3068 | 8 | : You may obtain a copy of the License at | ||
3069 | 9 | : | ||
3070 | 10 | : http://www.apache.org/licenses/LICENSE-2.0 | ||
3071 | 11 | : | ||
3072 | 12 | : Unless required by applicable law or agreed to in writing, software | ||
3073 | 13 | : distributed under the License is distributed on an "AS IS" BASIS, | ||
3074 | 14 | : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
3075 | 15 | : See the License for the specific language governing permissions and | ||
3076 | 16 | : limitations under the License. | ||
3077 | 17 | :) | ||
3078 | 18 | module namespace dmh = "http://www.zorba-xquery.com/modules/debugger/dbgp-message-handler"; | ||
3079 | 19 | |||
3080 | 20 | import module namespace base64 = "http://www.zorba-xquery.com/modules/converters/base64"; | ||
3081 | 21 | |||
3082 | 22 | declare namespace ver = "http://www.zorba-xquery.com/options/versioning"; | ||
3083 | 23 | declare option ver:module-version "1.0"; | ||
3084 | 24 | |||
3085 | 25 | |||
3086 | 26 | declare variable $dmh:endl as xs:string := " | ||
3087 | 27 | "; | ||
3088 | 28 | |||
3089 | 29 | (:~ | ||
3090 | 30 | : Set this variale to true if you want to have mode debug information when | ||
3091 | 31 | : an error occurs. | ||
3092 | 32 | :) | ||
3093 | 33 | declare variable $dmh:debug as xs:boolean := fn:false(); | ||
3094 | 34 | |||
3095 | 35 | |||
3096 | 36 | declare %private function dmh:status($resp as element(response)) | ||
3097 | 37 | { | ||
3098 | 38 | switch ($resp/@status) | ||
3099 | 39 | case "starting" | ||
3100 | 40 | case "stopping" | ||
3101 | 41 | return "idle" | ||
3102 | 42 | case "break" | ||
3103 | 43 | return | ||
3104 | 44 | let $status := $resp/@status | ||
3105 | 45 | let $whyInfo := | ||
3106 | 46 | if ($resp/@reason ne "ok") then | ||
3107 | 47 | fn:concat(" (", $resp/@reason, ")") | ||
3108 | 48 | else | ||
3109 | 49 | "" | ||
3110 | 50 | let $whereInfo := | ||
3111 | 51 | if ($resp/text()[1] ne "") then | ||
3112 | 52 | fn:concat(" in ", $resp/text()[1]) | ||
3113 | 53 | else | ||
3114 | 54 | "" | ||
3115 | 55 | return | ||
3116 | 56 | fn:concat($status, $whyInfo, $whereInfo) | ||
3117 | 57 | default | ||
3118 | 58 | return $resp/@status | ||
3119 | 59 | }; | ||
3120 | 60 | |||
3121 | 61 | declare %private function dmh:source($resp as element(response)) | ||
3122 | 62 | { | ||
3123 | 63 | $resp/text() | ||
3124 | 64 | }; | ||
3125 | 65 | |||
3126 | 66 | declare %private function dmh:breakpoint-set($resp as element(response)) | ||
3127 | 67 | { | ||
3128 | 68 | fn:concat("set breakpoint with id ", data($resp/@id), " and state ", data($resp/@state)) | ||
3129 | 69 | }; | ||
3130 | 70 | |||
3131 | 71 | declare %private function dmh:breakpoint-get($resp as element(response)) | ||
3132 | 72 | { | ||
3133 | 73 | let $b := $resp/breakpoint | ||
3134 | 74 | return | ||
3135 | 75 | fn:concat( | ||
3136 | 76 | "Breakpoint ", $b/@id, $dmh:endl, | ||
3137 | 77 | " type: ", $b/@type, $dmh:endl, | ||
3138 | 78 | " file: ", $b/@filename, $dmh:endl, | ||
3139 | 79 | " line: ", $b/@lineno, $dmh:endl, | ||
3140 | 80 | " state: ", $b/@state | ||
3141 | 81 | ) | ||
3142 | 82 | }; | ||
3143 | 83 | |||
3144 | 84 | declare %private function dmh:breakpoint-list($resp as element(response)) | ||
3145 | 85 | { | ||
3146 | 86 | fn:string-join( | ||
3147 | 87 | let $bs := $resp/breakpoint | ||
3148 | 88 | return | ||
3149 | 89 | if (fn:exists($bs)) then | ||
3150 | 90 | fn:concat( | ||
3151 | 91 | "--------------------------------------", $dmh:endl, | ||
3152 | 92 | "| ID | State | Line | File", $dmh:endl, | ||
3153 | 93 | "|--------|-----------|--------|-------", $dmh:endl, | ||
3154 | 94 | fn:string-join( | ||
3155 | 95 | for $b in $bs | ||
3156 | 96 | return | ||
3157 | 97 | fn:concat( | ||
3158 | 98 | "| ", dmh:lpottl($b/@id, 6, " "), " ", | ||
3159 | 99 | "| ", if ($b/@state eq "enabled") then "enabled " else "disabled ", " ", | ||
3160 | 100 | "| ", dmh:lpottl($b/@lineno, 6, " "), " ", | ||
3161 | 101 | "| ", $b/@filename, $dmh:endl), | ||
3162 | 102 | "" | ||
3163 | 103 | ), | ||
3164 | 104 | "--------------------------------------", $dmh:endl | ||
3165 | 105 | ) | ||
3166 | 106 | else | ||
3167 | 107 | "No breakpoints set" | ||
3168 | 108 | ) | ||
3169 | 109 | }; | ||
3170 | 110 | |||
3171 | 111 | (:~ | ||
3172 | 112 | : left-pad-or-trim-to-length | ||
3173 | 113 | :) | ||
3174 | 114 | declare %private function dmh:lpottl($value as xs:string, $length as xs:integer, $padChar as xs:string) | ||
3175 | 115 | as xs:string | ||
3176 | 116 | { | ||
3177 | 117 | let $padChar := fn:substring($padChar, 1, 1) | ||
3178 | 118 | let $len := fn:string-length($value) | ||
3179 | 119 | return | ||
3180 | 120 | if ($len < $length) then | ||
3181 | 121 | let $pad := | ||
3182 | 122 | fn:string-join( | ||
3183 | 123 | for $i in 1 to $length - $len | ||
3184 | 124 | return $padChar, | ||
3185 | 125 | "" | ||
3186 | 126 | ) | ||
3187 | 127 | return | ||
3188 | 128 | fn:concat($pad, $value) | ||
3189 | 129 | else | ||
3190 | 130 | fn:substring($value, $len - $length + 1) | ||
3191 | 131 | }; | ||
3192 | 132 | |||
3193 | 133 | declare %private function dmh:breakpoint-remove($resp as element(response)) | ||
3194 | 134 | { | ||
3195 | 135 | "Breakpoint removed" | ||
3196 | 136 | }; | ||
3197 | 137 | |||
3198 | 138 | declare %private function dmh:stack-depth($resp as element(response)) | ||
3199 | 139 | { | ||
3200 | 140 | fn:concat("depth: ", $resp/@depth) | ||
3201 | 141 | }; | ||
3202 | 142 | |||
3203 | 143 | declare %private function dmh:stack-get($resp as element(response)) | ||
3204 | 144 | { | ||
3205 | 145 | fn:string-join( | ||
3206 | 146 | for $s in $resp/stack | ||
3207 | 147 | return | ||
3208 | 148 | fn:concat("#", $s/@level, " in ", $s/@where, " at ", $s/@filename, ":", $s/@lineno), | ||
3209 | 149 | $dmh:endl | ||
3210 | 150 | ) | ||
3211 | 151 | }; | ||
3212 | 152 | |||
3213 | 153 | |||
3214 | 154 | declare %private function dmh:context-names($resp as element(response)) | ||
3215 | 155 | { | ||
3216 | 156 | fn:string-join( | ||
3217 | 157 | for $c in $resp/context | ||
3218 | 158 | return | ||
3219 | 159 | fn:concat("context ", $c/@id, ": ", $c/@name), | ||
3220 | 160 | $dmh:endl | ||
3221 | 161 | ) | ||
3222 | 162 | }; | ||
3223 | 163 | |||
3224 | 164 | declare %private function dmh:context-get($resp as element(response)) | ||
3225 | 165 | { | ||
3226 | 166 | fn:string-join( | ||
3227 | 167 | for $p in $resp/property | ||
3228 | 168 | return | ||
3229 | 169 | fn:concat($p/@fullname, " ", $p/@type, | ||
3230 | 170 | if ($p/text() ne "") then | ||
3231 | 171 | fn:concat(": ", base64:decode($p/text())) | ||
3232 | 172 | else | ||
3233 | 173 | "" | ||
3234 | 174 | ), | ||
3235 | 175 | $dmh:endl | ||
3236 | 176 | ) | ||
3237 | 177 | }; | ||
3238 | 178 | |||
3239 | 179 | declare %private function dmh:eval($resp as element(response)) | ||
3240 | 180 | { | ||
3241 | 181 | if ($resp/@success eq "1") then | ||
3242 | 182 | dmh:context-get($resp) | ||
3243 | 183 | else | ||
3244 | 184 | dmh:report-error("An unknown error occured while evaluating expression.") | ||
3245 | 185 | }; | ||
3246 | 186 | |||
3247 | 187 | declare %private function dmh:report-error( | ||
3248 | 188 | $message as xs:string) | ||
3249 | 189 | { | ||
3250 | 190 | dmh:report-error($message, ()) | ||
3251 | 191 | }; | ||
3252 | 192 | |||
3253 | 193 | declare %private function dmh:report-error( | ||
3254 | 194 | $message as xs:string, | ||
3255 | 195 | $debugMessage as xs:string*) | ||
3256 | 196 | { | ||
3257 | 197 | fn:string-join( | ||
3258 | 198 | ( | ||
3259 | 199 | (: the error message :) | ||
3260 | 200 | fn:concat("Error: ", $message), | ||
3261 | 201 | |||
3262 | 202 | (: the debug info :) | ||
3263 | 203 | if ($dmh:debug and fn:string-length($debugMessage) gt 0) then | ||
3264 | 204 | $debugMessage | ||
3265 | 205 | else | ||
3266 | 206 | () | ||
3267 | 207 | ), | ||
3268 | 208 | $dmh:endl | ||
3269 | 209 | ) | ||
3270 | 210 | }; | ||
3271 | 211 | |||
3272 | 212 | declare %private function dmh:process-response($resp as element(response)) | ||
3273 | 213 | { | ||
3274 | 214 | switch ($resp/@command) | ||
3275 | 215 | case "eval" return dmh:eval($resp) | ||
3276 | 216 | case "context_get" return dmh:context-get($resp) | ||
3277 | 217 | case "context_names" return dmh:context-names($resp) | ||
3278 | 218 | case "stack_get" return dmh:stack-get($resp) | ||
3279 | 219 | case "stack_depth" return dmh:stack-depth($resp) | ||
3280 | 220 | case "breakpoint_remove" return dmh:breakpoint-remove($resp) | ||
3281 | 221 | case "breakpoint_list" return dmh:breakpoint-list($resp) | ||
3282 | 222 | case "breakpoint_get" return dmh:breakpoint-get($resp) | ||
3283 | 223 | case "breakpoint_set" return dmh:breakpoint-set($resp) | ||
3284 | 224 | case "source" return dmh:source($resp) | ||
3285 | 225 | |||
3286 | 226 | (: continuation command only need to display/process the status :) | ||
3287 | 227 | case "run" | ||
3288 | 228 | case "step_into" | ||
3289 | 229 | case "step_out" | ||
3290 | 230 | case "step_over" | ||
3291 | 231 | case "stop" | ||
3292 | 232 | case "status" | ||
3293 | 233 | return dmh:status($resp) | ||
3294 | 234 | |||
3295 | 235 | default | ||
3296 | 236 | return dmh:report-error(fn:concat("Command not implemented: ", $resp/@command)) | ||
3297 | 237 | }; | ||
3298 | 238 | |||
3299 | 239 | declare function dmh:process-init($init as element(init)) | ||
3300 | 240 | { | ||
3301 | 241 | fn:string-join( | ||
3302 | 242 | ("Established connection with", $init/@language, "client", $init/@appid), | ||
3303 | 243 | " " | ||
3304 | 244 | ) | ||
3305 | 245 | }; | ||
3306 | 246 | |||
3307 | 247 | declare function dmh:process($message as element()) | ||
3308 | 248 | { | ||
3309 | 249 | let $nodeName := fn:local-name($message) | ||
3310 | 250 | let $id := fn:data($message/@transaction_id) | ||
3311 | 251 | return | ||
3312 | 252 | if ($nodeName eq "response") then | ||
3313 | 253 | (: no transaction_id :) | ||
3314 | 254 | if (fn:count($id) eq 0 or $id eq "") then | ||
3315 | 255 | (0, dmh:report-error("Invalid response", "Missing or empty response transaction ID.")) | ||
3316 | 256 | (: wrong transaction_id :) | ||
3317 | 257 | else if (xs:string(fn:number($id)) eq "NaN") then | ||
3318 | 258 | (0, dmh:report-error("Invalid response", "Invalid value for response transaction ID.")) | ||
3319 | 259 | (: no or empty command :) | ||
3320 | 260 | else if (fn:count($message/@command) eq 0 or $message/@command eq "") then | ||
3321 | 261 | ($id, dmh:report-error("Invalid response", "Missing or empty response command attribute.")) | ||
3322 | 262 | (: error response :) | ||
3323 | 263 | else if (fn:exists($message/error)) then | ||
3324 | 264 | ($id, dmh:report-error(fn:data($message/error/message), fn:concat("Error code: ", fn:data($message/error/@code)))) | ||
3325 | 265 | else | ||
3326 | 266 | ($id, dmh:process-response($message)) | ||
3327 | 267 | else if ($nodeName eq "init") then | ||
3328 | 268 | (0, dmh:process-init($message)) | ||
3329 | 269 | else | ||
3330 | 270 | ( | ||
3331 | 271 | if (fn:count($id) eq 0 or $id eq "" or xs:string(fn:number($id)) eq "NaN") then | ||
3332 | 272 | 0 | ||
3333 | 273 | else | ||
3334 | 274 | $id, | ||
3335 | 275 | dmh:report-error(fn:concat("Unknown message node: ", $nodeName)) | ||
3336 | 276 | ) | ||
3337 | 277 | }; | ||
3338 | 0 | 278 | ||
3339 | === modified file 'src/compiler/expression/expr.cpp' | |||
3340 | --- src/compiler/expression/expr.cpp 2011-12-20 09:04:58 +0000 | |||
3341 | +++ src/compiler/expression/expr.cpp 2011-12-20 18:15:30 +0000 | |||
3342 | @@ -1469,7 +1469,6 @@ | |||
3343 | 1469 | compute_scripting_kind(); | 1469 | compute_scripting_kind(); |
3344 | 1470 | } | 1470 | } |
3345 | 1471 | 1471 | ||
3346 | 1472 | |||
3347 | 1473 | void debugger_expr::serialize(::zorba::serialization::Archiver& ar) | 1472 | void debugger_expr::serialize(::zorba::serialization::Archiver& ar) |
3348 | 1474 | { | 1473 | { |
3349 | 1475 | serialize_baseclass(ar, (expr*)this); | 1474 | serialize_baseclass(ar, (expr*)this); |
3350 | 1476 | 1475 | ||
3351 | === modified file 'src/compiler/translator/translator.cpp' | |||
3352 | --- src/compiler/translator/translator.cpp 2011-12-20 11:50:23 +0000 | |||
3353 | +++ src/compiler/translator/translator.cpp 2011-12-20 18:15:30 +0000 | |||
3354 | @@ -1671,7 +1671,7 @@ | |||
3355 | 1671 | void wrap_in_debugger_expr( | 1671 | void wrap_in_debugger_expr( |
3356 | 1672 | expr_t& aExpr, | 1672 | expr_t& aExpr, |
3357 | 1673 | const QueryLoc& aLoc, | 1673 | const QueryLoc& aLoc, |
3359 | 1674 | bool aAddBreakable = true, | 1674 | bool aIsMainModuleBreakable = false, |
3360 | 1675 | bool aIsVarDeclaration = false) | 1675 | bool aIsVarDeclaration = false) |
3361 | 1676 | { | 1676 | { |
3362 | 1677 | #ifdef ZORBA_WITH_DEBUGGER | 1677 | #ifdef ZORBA_WITH_DEBUGGER |
3363 | @@ -1686,9 +1686,7 @@ | |||
3364 | 1686 | // add the breakable expression in the debugger commons as a possible | 1686 | // add the breakable expression in the debugger commons as a possible |
3365 | 1687 | // breakpoint location | 1687 | // breakpoint location |
3366 | 1688 | Breakable lBreakable(aLoc); | 1688 | Breakable lBreakable(aLoc); |
3370 | 1689 | if (aAddBreakable) { | 1689 | theCCB->theDebuggerCommons->addBreakable(lBreakable, aIsMainModuleBreakable); |
3368 | 1690 | theCCB->theDebuggerCommons->addBreakable(lBreakable); | ||
3369 | 1691 | } | ||
3371 | 1692 | 1690 | ||
3372 | 1693 | // retrieve all variables that are in the current scope | 1691 | // retrieve all variables that are in the current scope |
3373 | 1694 | typedef std::vector<var_expr_t> VarExprVector; | 1692 | typedef std::vector<var_expr_t> VarExprVector; |
3374 | @@ -2246,7 +2244,7 @@ | |||
3375 | 2246 | // the main module debug iterator has no location otherwise | 2244 | // the main module debug iterator has no location otherwise |
3376 | 2247 | // this would take precedence over a child debug iterator | 2245 | // this would take precedence over a child debug iterator |
3377 | 2248 | // starting in the same line | 2246 | // starting in the same line |
3379 | 2249 | wrap_in_debugger_expr(program, program->get_loc(), false); | 2247 | wrap_in_debugger_expr(program, program->get_loc(), true); |
3380 | 2250 | 2248 | ||
3381 | 2251 | program = wrap_in_globalvar_assign(program); | 2249 | program = wrap_in_globalvar_assign(program); |
3382 | 2252 | 2250 | ||
3383 | @@ -3725,7 +3723,7 @@ | |||
3384 | 3725 | QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(), | 3723 | QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(), |
3385 | 3726 | initExpr->get_loc()); | 3724 | initExpr->get_loc()); |
3386 | 3727 | 3725 | ||
3388 | 3728 | wrap_in_debugger_expr(initExpr, lExpandedLocation, true, true); | 3726 | wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true); |
3389 | 3729 | } | 3727 | } |
3390 | 3730 | #endif | 3728 | #endif |
3391 | 3731 | 3729 | ||
3392 | @@ -3747,7 +3745,7 @@ | |||
3393 | 3747 | QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(), | 3745 | QueryLoc lExpandedLocation = expandQueryLoc(v.get_name()->get_location(), |
3394 | 3748 | initExpr->get_loc()); | 3746 | initExpr->get_loc()); |
3395 | 3749 | 3747 | ||
3397 | 3750 | wrap_in_debugger_expr(initExpr, lExpandedLocation, true, true); | 3748 | wrap_in_debugger_expr(initExpr, lExpandedLocation, false, true); |
3398 | 3751 | } | 3749 | } |
3399 | 3752 | #endif | 3750 | #endif |
3400 | 3753 | 3751 | ||
3401 | 3754 | 3752 | ||
3402 | === modified file 'src/debugger/debugger_client.cpp' | |||
3403 | --- src/debugger/debugger_client.cpp 2011-06-14 17:26:33 +0000 | |||
3404 | +++ src/debugger/debugger_client.cpp 2011-12-20 18:15:30 +0000 | |||
3405 | @@ -38,5 +38,3 @@ | |||
3406 | 38 | } | 38 | } |
3407 | 39 | 39 | ||
3408 | 40 | }//end of namespace | 40 | }//end of namespace |
3409 | 41 | |||
3410 | 42 | /* vim:set et sw=2 ts=2: */ | ||
3411 | 43 | 41 | ||
3412 | === modified file 'src/debugger/debugger_clientimpl.cpp' | |||
3413 | --- src/debugger/debugger_clientimpl.cpp 2011-07-06 20:43:46 +0000 | |||
3414 | +++ src/debugger/debugger_clientimpl.cpp 2011-12-20 18:15:30 +0000 | |||
3415 | @@ -24,462 +24,549 @@ | |||
3416 | 24 | 24 | ||
3417 | 25 | namespace zorba { | 25 | namespace zorba { |
3418 | 26 | 26 | ||
3430 | 27 | DebuggerClient::~DebuggerClient() | 27 | DebuggerClient* |
3431 | 28 | {} | 28 | DebuggerClient::createDebuggerClient( |
3432 | 29 | 29 | DebuggerEventHandler* aHandler, | |
3433 | 30 | DebuggerClient* DebuggerClient::createDebuggerClient(DebuggerEventHandler* aHandler, | 30 | unsigned short aPort, |
3434 | 31 | unsigned short aPort, | 31 | const std::string& aHost) |
3435 | 32 | const std::string& aHost) | 32 | { |
3436 | 33 | { | 33 | return new DebuggerClientImpl(aHost, aPort, aHandler); |
3437 | 34 | return new DebuggerClientImpl(aHost, aPort, aHandler); | 34 | } |
3438 | 35 | } | 35 | |
3439 | 36 | 36 | // **************************************************************************** | |
3440 | 37 | DebuggerListener::DebuggerListener(DebuggerClientImpl* aClient) | 37 | |
3441 | 38 | DebuggerListener::DebuggerListener(DebuggerClientImpl* aClient) | ||
3442 | 38 | : theClient(aClient), theStopLooping(false) | 39 | : theClient(aClient), theStopLooping(false) |
3890 | 39 | { | 40 | { |
3891 | 40 | } | 41 | } |
3892 | 41 | 42 | ||
3893 | 42 | void DebuggerListener::run() | 43 | void |
3894 | 43 | { | 44 | DebuggerListener::run() |
3895 | 44 | while (!theStopLooping) { | 45 | { |
3896 | 45 | std::string str; | 46 | while (!theStopLooping) { |
3897 | 46 | std::getline(*(theClient->theStream), str, '\0'); | 47 | std::string str; |
3898 | 47 | #ifndef NDEBUG | 48 | std::getline(*(theClient->theInStream), str, '\0'); |
3899 | 48 | std::stringstream lStr(str); | 49 | |
3900 | 49 | std::size_t length; | 50 | #ifndef NDEBUG |
3901 | 50 | lStr >> length; | 51 | std::stringstream lStr(str); |
3902 | 51 | #endif | 52 | std::size_t length; |
3903 | 52 | // we are not interested in the length, but only in the init | 53 | lStr >> length; |
3904 | 53 | // message | 54 | #endif |
3905 | 54 | std::getline(*(theClient->theStream), str, '\0'); | 55 | |
3906 | 55 | #ifndef NDEBUG | 56 | // we are not interested in the length, but only in the init message |
3907 | 56 | assert(str.size() == length); | 57 | std::getline(*(theClient->theInStream), str, '\0'); |
3908 | 57 | #endif | 58 | |
3909 | 58 | theClient->theHandler->parseMessage(str); | 59 | #ifndef NDEBUG |
3910 | 59 | this->sleep_(1000); | 60 | assert(str.size() == length); |
3911 | 60 | } | 61 | #endif |
3912 | 61 | } | 62 | |
3913 | 62 | 63 | theClient->theHandler->parseMessage(str); | |
3914 | 63 | void DebuggerListener::finish() | 64 | |
3915 | 64 | { | 65 | // TODO: this was the initial implementation. This will have to change |
3916 | 65 | } | 66 | this->sleep_(1000); |
3917 | 66 | 67 | } | |
3918 | 67 | void DebuggerListener::stopLooping() | 68 | } |
3919 | 68 | { | 69 | |
3920 | 69 | theStopLooping = true; | 70 | void |
3921 | 70 | } | 71 | DebuggerListener::finish() |
3922 | 71 | 72 | { | |
3923 | 72 | DebuggerClientImpl::DebuggerClientImpl(const std::string& aHost, | 73 | } |
3924 | 73 | unsigned short aPort, | 74 | |
3925 | 74 | DebuggerEventHandler* aHandler) | 75 | void |
3926 | 75 | : theServerSocket(aHost, aPort), theSocket(0), theStreamBuffer(0), theStream(0), | 76 | DebuggerListener::stopLooping() |
3927 | 76 | theHandler(aHandler), theListener(this), theLastId(0) | 77 | { |
3928 | 77 | { | 78 | theStopLooping = true; |
3929 | 78 | } | 79 | } |
3930 | 79 | 80 | ||
3931 | 80 | void DebuggerClientImpl::accept() { | 81 | // **************************************************************************** |
3932 | 81 | theSocket = theServerSocket.accept(); | 82 | |
3933 | 82 | theStreamBuffer = new socket_streambuf(*theSocket); | 83 | DebuggerClient::~DebuggerClient() |
3934 | 83 | theStream = new std::iostream(theStreamBuffer); | 84 | { |
3935 | 84 | theListener.start(); | 85 | } |
3936 | 85 | } | 86 | |
3937 | 86 | 87 | DebuggerClientImpl::DebuggerClientImpl( | |
3938 | 87 | std::size_t DebuggerClientImpl::status() | 88 | const std::string& aHost, |
3939 | 88 | { | 89 | unsigned short aPort, |
3940 | 89 | std::size_t id = ++theLastId; | 90 | DebuggerEventHandler* aHandler) |
3941 | 90 | *theStream << "status -i " << id << '\0'; | 91 | : theServerSocket(aHost, aPort), |
3942 | 91 | theStream->sync(); | 92 | theSocket(0), |
3943 | 92 | return id; | 93 | theInStreamBuffer(0), |
3944 | 93 | } | 94 | theOutStreamBuffer(0), |
3945 | 94 | 95 | theInStream(0), | |
3946 | 95 | std::size_t DebuggerClientImpl::feature_get(std::string const& aFeatureName) | 96 | theOutStream(0), |
3947 | 96 | { | 97 | theHandler(aHandler), |
3948 | 97 | std::size_t id = ++theLastId; | 98 | theListener(0), |
3949 | 98 | *theStream << "feature-get -i " << id << " -n " << aFeatureName << '\0'; | 99 | theLastId(0) |
3950 | 99 | theStream->sync(); | 100 | { |
3951 | 100 | return id; | 101 | } |
3952 | 101 | } | 102 | |
3953 | 102 | 103 | DebuggerClientImpl::~DebuggerClientImpl() | |
3954 | 103 | std::size_t DebuggerClientImpl::feature_set(std::string const &aFeatureName, | 104 | { |
3955 | 104 | std::string const &aValue) | 105 | if (theListener) { |
3956 | 105 | { | 106 | if (theListener->status() == DebuggerListener::RUNNING) { |
3957 | 106 | std::size_t id = ++theLastId; | 107 | theListener->stopLooping(); |
3958 | 107 | *theStream << "feature-set -i " << id << " -n " << aFeatureName << " -v " | 108 | theListener->join(); |
3959 | 108 | << aValue << '\0'; | 109 | } |
3960 | 109 | theStream->sync(); | 110 | delete theListener; |
3961 | 110 | return id; | 111 | } |
3962 | 111 | } | 112 | if (theSocket) { |
3963 | 112 | 113 | theInStream->sync(); | |
3964 | 113 | std::size_t DebuggerClientImpl::run() | 114 | delete theInStream; |
3965 | 114 | { | 115 | |
3966 | 115 | std::size_t id = ++theLastId; | 116 | theOutStream->flush(); |
3967 | 116 | *theStream << "run -i " << id << '\0'; | 117 | delete theInStream; |
3968 | 117 | theStream->sync(); | 118 | |
3969 | 118 | return id; | 119 | delete theOutStreamBuffer; |
3970 | 119 | } | 120 | delete theInStreamBuffer; |
3971 | 120 | 121 | ||
3972 | 121 | std::size_t DebuggerClientImpl::step_into() | 122 | theSocket->close(); |
3973 | 122 | { | 123 | theSocket->cleanUp(); |
3974 | 123 | std::size_t id = ++theLastId; | 124 | delete theSocket; |
3975 | 124 | *theStream << "step_into -i " << id << '\0'; | 125 | } |
3976 | 125 | theStream->sync(); | 126 | } |
3977 | 126 | return id; | 127 | |
3978 | 127 | } | 128 | void |
3979 | 128 | 129 | DebuggerClientImpl::accept() | |
3980 | 129 | std::size_t DebuggerClientImpl::step_over() | 130 | { |
3981 | 130 | { | 131 | theListener = new DebuggerListener(this); |
3982 | 131 | std::size_t id = ++theLastId; | 132 | theSocket = theServerSocket.accept(); |
3983 | 132 | *theStream << "step_over -i " << id << '\0'; | 133 | theInStreamBuffer = new SocketStreambuf(*theSocket); |
3984 | 133 | theStream->sync(); | 134 | theOutStreamBuffer = new SocketStreambuf(*theSocket); |
3985 | 134 | return id; | 135 | theInStream = new std::istream(theInStreamBuffer); |
3986 | 135 | } | 136 | theOutStream = new std::ostream(theOutStreamBuffer); |
3987 | 136 | 137 | theListener->start(); | |
3988 | 137 | std::size_t DebuggerClientImpl::step_out() | 138 | } |
3989 | 138 | { | 139 | |
3990 | 139 | std::size_t id = ++theLastId; | 140 | std::size_t |
3991 | 140 | *theStream << "step_out -i " << id << '\0'; | 141 | DebuggerClientImpl::status() |
3992 | 141 | theStream->sync(); | 142 | { |
3993 | 142 | return id; | 143 | std::size_t id = ++theLastId; |
3994 | 143 | } | 144 | *theOutStream << "status -i " << id << '\0'; |
3995 | 144 | 145 | theOutStream->flush(); | |
3996 | 145 | std::size_t DebuggerClientImpl::stop() | 146 | return id; |
3997 | 146 | { | 147 | } |
3998 | 147 | std::size_t id = ++theLastId; | 148 | |
3999 | 148 | *theStream << "stop -i " << id << '\0'; | 149 | std::size_t |
4000 | 149 | theStream->sync(); | 150 | DebuggerClientImpl::variables() |
4001 | 150 | return id; | 151 | { |
4002 | 151 | } | 152 | // we hack the protocol to return all properties if the context ID is -1 |
4003 | 152 | 153 | std::size_t id = ++theLastId; | |
4004 | 153 | std::size_t DebuggerClientImpl::detach() | 154 | *theOutStream << "context_get -c -1 -i " << id << '\0'; |
4005 | 154 | { | 155 | theOutStream->flush(); |
4006 | 155 | std::size_t id = ++theLastId; | 156 | return id; |
4007 | 156 | *theStream << "detach -i " << id << '\0'; | 157 | } |
4008 | 157 | theStream->sync(); | 158 | |
4009 | 158 | return id; | 159 | std::size_t |
4010 | 159 | } | 160 | DebuggerClientImpl::feature_get(std::string const& aFeatureName) |
4011 | 160 | 161 | { | |
4012 | 161 | std::size_t DebuggerClientImpl::breakpoint_set(BreakpointType aType, | 162 | std::size_t id = ++theLastId; |
4013 | 162 | bool aEnabled, | 163 | *theOutStream << "feature_get -i " << id << " -n " << aFeatureName << '\0'; |
4014 | 163 | const std::string& aFilename, | 164 | theOutStream->flush(); |
4015 | 164 | int aLinenumber, | 165 | return id; |
4016 | 165 | const std::string& aFunctionName, | 166 | } |
4017 | 166 | const std::string& aExceptionName, | 167 | |
4018 | 167 | unsigned hit_value, | 168 | std::size_t |
4019 | 168 | HitCondition aCondition, | 169 | DebuggerClientImpl::feature_set(std::string const &aFeatureName, |
4020 | 169 | bool aIsTemporary, | 170 | std::string const &aValue) |
4021 | 170 | const std::string& aExpression) | 171 | { |
4022 | 171 | { | 172 | std::size_t id = ++theLastId; |
4023 | 172 | std::size_t id = ++theLastId; | 173 | *theOutStream << "feature_set -i " << id << " -n " << aFeatureName << " -v " |
4024 | 173 | *theStream << "breakpoint_set -i " << id | 174 | << aValue << '\0'; |
4025 | 174 | << " -t "; | 175 | theOutStream->flush(); |
4026 | 175 | switch (aType) { | 176 | return id; |
4027 | 176 | case Line: | 177 | } |
4028 | 177 | *theStream << "line"; | 178 | |
4029 | 178 | break; | 179 | std::size_t |
4030 | 179 | case Call: | 180 | DebuggerClientImpl::run() |
4031 | 180 | *theStream << "call"; | 181 | { |
4032 | 181 | break; | 182 | std::size_t id = ++theLastId; |
4033 | 182 | case Return: | 183 | *theOutStream << "run -i " << id << '\0'; |
4034 | 183 | *theStream << "return"; | 184 | theOutStream->flush(); |
4035 | 184 | break; | 185 | return id; |
4036 | 185 | case Exception: | 186 | } |
4037 | 186 | *theStream << "exception"; | 187 | |
4038 | 187 | break; | 188 | std::size_t |
4039 | 188 | case Conditional: | 189 | DebuggerClientImpl::step_into() |
4040 | 189 | *theStream << "conditional"; | 190 | { |
4041 | 190 | break; | 191 | std::size_t id = ++theLastId; |
4042 | 191 | case Watch: | 192 | *theOutStream << "step_into -i " << id << '\0'; |
4043 | 192 | *theStream << "watch"; | 193 | theOutStream->flush(); |
4044 | 193 | break; | 194 | return id; |
4045 | 194 | } | 195 | } |
4046 | 195 | if (!aEnabled) | 196 | |
4047 | 196 | *theStream << " -s disabled"; | 197 | std::size_t |
4048 | 197 | if (aFilename != "") { | 198 | DebuggerClientImpl::step_over() |
4049 | 198 | *theStream << " -f " << aFilename; | 199 | { |
4050 | 199 | } | 200 | std::size_t id = ++theLastId; |
4051 | 200 | if (aLinenumber != -1) | 201 | *theOutStream << "step_over -i " << id << '\0'; |
4052 | 201 | *theStream << " -n " << aLinenumber; | 202 | theOutStream->flush(); |
4053 | 202 | if (aFunctionName != "") | 203 | return id; |
4054 | 203 | *theStream << " -m " << aFunctionName; | 204 | } |
4055 | 204 | if (aExceptionName != "") | 205 | |
4056 | 205 | *theStream << " -x " << aExceptionName; | 206 | std::size_t |
4057 | 206 | if (hit_value != 0) | 207 | DebuggerClientImpl::step_out() |
4058 | 207 | *theStream << " -h " << hit_value; | 208 | { |
4059 | 208 | switch (aCondition) { | 209 | std::size_t id = ++theLastId; |
4060 | 209 | case BiggerEqual: | 210 | *theOutStream << "step_out -i " << id << '\0'; |
4061 | 210 | break; | 211 | theOutStream->flush(); |
4062 | 211 | case Equal: | 212 | return id; |
4063 | 212 | *theStream << " -o == "; | 213 | } |
4064 | 213 | break; | 214 | |
4065 | 214 | case Multiple: | 215 | std::size_t |
4066 | 215 | *theStream << " -o % "; | 216 | DebuggerClientImpl::stop() |
4067 | 216 | } | 217 | { |
4068 | 217 | if (aIsTemporary) | 218 | std::size_t id = ++theLastId; |
4069 | 218 | *theStream << " -r 1 "; | 219 | *theOutStream << "stop -i " << id << '\0'; |
4070 | 219 | if (aExpression != "") | 220 | theOutStream->flush(); |
4071 | 220 | *theStream << " -- " << aExpression; | 221 | return id; |
4072 | 221 | *theStream << '\0'; | 222 | } |
4073 | 222 | theStream->sync(); | 223 | |
4074 | 223 | return id; | 224 | std::size_t |
4075 | 224 | } | 225 | DebuggerClientImpl::detach() |
4076 | 225 | 226 | { | |
4077 | 226 | std::size_t DebuggerClientImpl::breakpoint_get(std::size_t aBreakpointId) | 227 | std::size_t id = ++theLastId; |
4078 | 227 | { | 228 | *theOutStream << "detach -i " << id << '\0'; |
4079 | 228 | std::size_t id = ++theLastId; | 229 | theOutStream->flush(); |
4080 | 229 | *theStream << "breakpoint_get -i " << id << " -d " << aBreakpointId << '\0'; | 230 | return id; |
4081 | 230 | theStream->sync(); | 231 | } |
4082 | 231 | return id; | 232 | |
4083 | 232 | } | 233 | std::size_t |
4084 | 233 | 234 | DebuggerClientImpl::breakpoint_set( | |
4085 | 234 | std::size_t DebuggerClientImpl::breakpoint_update(std::size_t aBreakpointId, | 235 | BreakpointType aType, |
4086 | 235 | bool aEnabled, | 236 | bool aEnabled, |
4087 | 236 | int aLinenumber, | 237 | const std::string& aFilename, |
4088 | 237 | unsigned hit_value, | 238 | int aLinenumber, |
4089 | 238 | HitCondition aCondition) | 239 | const std::string& aFunctionName, |
4090 | 239 | { | 240 | const std::string& aExceptionName, |
4091 | 240 | std::size_t id = ++theLastId; | 241 | unsigned hit_value, |
4092 | 241 | *theStream << "breakpoint_update -i " << id | 242 | HitCondition aCondition, |
4093 | 242 | << " -d " << aBreakpointId; | 243 | bool aIsTemporary, |
4094 | 243 | if (aEnabled) | 244 | const std::string& aExpression) |
4095 | 244 | *theStream << " -s disabled"; | 245 | { |
4096 | 245 | if (aLinenumber != -1) | 246 | std::size_t id = ++theLastId; |
4097 | 246 | *theStream << " -n " << aLinenumber; | 247 | *theOutStream << "breakpoint_set -i " << id |
4098 | 247 | if (hit_value != 0) | 248 | << " -t "; |
4099 | 248 | *theStream << " -h " << hit_value; | 249 | switch (aType) { |
4100 | 249 | switch (aCondition) { | 250 | case Line: |
4101 | 250 | case BiggerEqual: | 251 | *theOutStream << "line"; |
4102 | 251 | break; | 252 | break; |
4103 | 252 | case Equal: | 253 | case Call: |
4104 | 253 | *theStream << " -o == "; | 254 | *theOutStream << "call"; |
4105 | 254 | break; | 255 | break; |
4106 | 255 | case Multiple: | 256 | case Return: |
4107 | 256 | *theStream << " -o % "; | 257 | *theOutStream << "return"; |
4108 | 257 | } | 258 | break; |
4109 | 258 | *theStream << '\0'; | 259 | case Exception: |
4110 | 259 | theStream->sync(); | 260 | *theOutStream << "exception"; |
4111 | 260 | return id; | 261 | break; |
4112 | 261 | } | 262 | case Conditional: |
4113 | 262 | 263 | *theOutStream << "conditional"; | |
4114 | 263 | std::size_t DebuggerClientImpl::breakpoint_remove(std::size_t aBreakpointId) | 264 | break; |
4115 | 264 | { | 265 | case Watch: |
4116 | 265 | std::size_t id = ++theLastId; | 266 | *theOutStream << "watch"; |
4117 | 266 | *theStream << "breakpoint_remove -i " << id << " -d " << aBreakpointId << '\0'; | 267 | break; |
4118 | 267 | theStream->sync(); | 268 | } |
4119 | 268 | return id; | 269 | if (!aEnabled) |
4120 | 269 | } | 270 | *theOutStream << " -s disabled"; |
4121 | 270 | 271 | if (aFilename != "") { | |
4122 | 271 | std::size_t DebuggerClientImpl::breakpoint_list() | 272 | *theOutStream << " -f \"" << aFilename << "\""; |
4123 | 272 | { | 273 | } |
4124 | 273 | std::size_t id = ++theLastId; | 274 | if (aLinenumber != -1) |
4125 | 274 | *theStream << "breakpoint_list -i " << id << '\0'; | 275 | *theOutStream << " -n " << aLinenumber; |
4126 | 275 | theStream->sync(); | 276 | if (aFunctionName != "") |
4127 | 276 | return id; | 277 | *theOutStream << " -m " << aFunctionName; |
4128 | 277 | } | 278 | if (aExceptionName != "") |
4129 | 278 | 279 | *theOutStream << " -x " << aExceptionName; | |
4130 | 279 | std::size_t DebuggerClientImpl::stack_depth() | 280 | if (hit_value != 0) |
4131 | 280 | { | 281 | *theOutStream << " -h " << hit_value; |
4132 | 281 | std::size_t id = ++theLastId; | 282 | switch (aCondition) { |
4133 | 282 | *theStream << "stack_depth -i " << id << '\0'; | 283 | case BiggerEqual: |
4134 | 283 | theStream->sync(); | 284 | break; |
4135 | 284 | return id; | 285 | case Equal: |
4136 | 285 | } | 286 | *theOutStream << " -o == "; |
4137 | 286 | 287 | break; | |
4138 | 287 | std::size_t DebuggerClientImpl::stack_get(int depth) | 288 | case Multiple: |
4139 | 288 | { | 289 | *theOutStream << " -o % "; |
4140 | 289 | std::size_t id = ++theLastId; | 290 | } |
4141 | 290 | *theStream << "stack_depth"; | 291 | if (aIsTemporary) |
4142 | 291 | if (depth > 0) | 292 | *theOutStream << " -r 1 "; |
4143 | 292 | *theStream << " -d " << depth; | 293 | if (aExpression != "") |
4144 | 293 | *theStream << " -i " << id << '\0'; | 294 | *theOutStream << " -- " << aExpression; |
4145 | 294 | theStream->sync(); | 295 | *theOutStream << '\0'; |
4146 | 295 | return id; | 296 | theOutStream->flush(); |
4147 | 296 | } | 297 | return id; |
4148 | 297 | 298 | } | |
4149 | 298 | std::size_t DebuggerClientImpl::context_names(int depth) | 299 | |
4150 | 299 | { | 300 | std::size_t |
4151 | 300 | std::size_t id = ++theLastId; | 301 | DebuggerClientImpl::breakpoint_get(std::size_t aBreakpointId) |
4152 | 301 | *theStream << "context_names"; | 302 | { |
4153 | 302 | if (depth > 0) | 303 | std::size_t id = ++theLastId; |
4154 | 303 | *theStream << " -d " << depth; | 304 | *theOutStream << "breakpoint_get -i " << id << " -d " << aBreakpointId << '\0'; |
4155 | 304 | *theStream << " -i " << id << '\0'; | 305 | theOutStream->flush(); |
4156 | 305 | theStream->sync(); | 306 | return id; |
4157 | 306 | return id; | 307 | } |
4158 | 307 | } | 308 | |
4159 | 308 | 309 | std::size_t | |
4160 | 309 | std::size_t DebuggerClientImpl::context_get(int depth, int contextId) | 310 | DebuggerClientImpl::breakpoint_update( |
4161 | 310 | { | 311 | std::size_t aBreakpointId, |
4162 | 311 | std::size_t id = ++theLastId; | 312 | bool aEnabled, |
4163 | 312 | *theStream << "context_get"; | 313 | int aLinenumber, |
4164 | 313 | if (depth > 0) | 314 | unsigned hit_value, |
4165 | 314 | *theStream << " -d " << depth; | 315 | HitCondition aCondition) |
4166 | 315 | if (contextId > 0) | 316 | { |
4167 | 316 | *theStream << " -c " << contextId; | 317 | std::size_t id = ++theLastId; |
4168 | 317 | *theStream << " -i " << id << '\0'; | 318 | *theOutStream << "breakpoint_update -i " << id |
4169 | 318 | theStream->sync(); | 319 | << " -d " << aBreakpointId; |
4170 | 319 | return id; | 320 | if (aEnabled) |
4171 | 320 | } | 321 | *theOutStream << " -s disabled"; |
4172 | 321 | 322 | if (aLinenumber != -1) | |
4173 | 322 | std::size_t DebuggerClientImpl::typemap_get() | 323 | *theOutStream << " -n " << aLinenumber; |
4174 | 323 | { | 324 | if (hit_value != 0) |
4175 | 324 | std::size_t id = ++theLastId; | 325 | *theOutStream << " -h " << hit_value; |
4176 | 325 | *theStream << "typemap_get -i " << id << '\0'; | 326 | switch (aCondition) { |
4177 | 326 | theStream->sync(); | 327 | case BiggerEqual: |
4178 | 327 | return id; | 328 | break; |
4179 | 328 | } | 329 | case Equal: |
4180 | 329 | 330 | *theOutStream << " -o == "; | |
4181 | 330 | std::size_t DebuggerClientImpl::property_get(const std::string& aPropertyLongName, | 331 | break; |
4182 | 331 | int aStackDepth, | 332 | case Multiple: |
4183 | 332 | int aContextId, | 333 | *theOutStream << " -o % "; |
4184 | 333 | std::size_t aMaxDataSize, | 334 | } |
4185 | 334 | int aDatapage, | 335 | *theOutStream << '\0'; |
4186 | 335 | const std::string& aPropertyKey) | 336 | theOutStream->flush(); |
4187 | 336 | { | 337 | return id; |
4188 | 337 | std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize); | 338 | } |
4189 | 338 | if (aDatapage >= 0) | 339 | |
4190 | 339 | *theStream << " -p " << aDatapage; | 340 | std::size_t |
4191 | 340 | if (aPropertyKey != "") | 341 | DebuggerClientImpl::breakpoint_remove(std::size_t aBreakpointId) |
4192 | 341 | *theStream << " -k " << aPropertyKey; | 342 | { |
4193 | 342 | *theStream << '\0'; | 343 | std::size_t id = ++theLastId; |
4194 | 343 | theStream->sync(); | 344 | *theOutStream << "breakpoint_remove -i " << id << " -d " << aBreakpointId << '\0'; |
4195 | 344 | return id; | 345 | theOutStream->flush(); |
4196 | 345 | } | 346 | return id; |
4197 | 346 | 347 | } | |
4198 | 347 | std::size_t DebuggerClientImpl::property_set(const std::string& aPropertyLongName, | 348 | |
4199 | 348 | int aStackDepth, | 349 | std::size_t |
4200 | 349 | int aContextId, | 350 | DebuggerClientImpl::breakpoint_list() |
4201 | 350 | std::size_t aMaxDataSize, | 351 | { |
4202 | 351 | const std::string& aPropertyAddress) | 352 | std::size_t id = ++theLastId; |
4203 | 352 | { | 353 | *theOutStream << "breakpoint_list -i " << id << '\0'; |
4204 | 353 | std::size_t id = property_x("property_set", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize); | 354 | theOutStream->flush(); |
4205 | 354 | if (aPropertyAddress != "") | 355 | return id; |
4206 | 355 | *theStream << " -a " << aPropertyAddress; | 356 | } |
4207 | 356 | *theStream << '\0'; | 357 | |
4208 | 357 | theStream->sync(); | 358 | std::size_t |
4209 | 358 | return id; | 359 | DebuggerClientImpl::stack_depth() |
4210 | 359 | } | 360 | { |
4211 | 360 | 361 | std::size_t id = ++theLastId; | |
4212 | 361 | std::size_t DebuggerClientImpl::property_value(const std::string& aPropertyLongName, | 362 | *theOutStream << "stack_depth -i " << id << '\0'; |
4213 | 362 | int aStackDepth, | 363 | theOutStream->flush(); |
4214 | 363 | int aContextId, | 364 | return id; |
4215 | 364 | std::size_t aMaxDataSize, | 365 | } |
4216 | 365 | int aDatapage, | 366 | |
4217 | 366 | const std::string& aPropertyKey, | 367 | std::size_t |
4218 | 367 | const std::string& aPropertyAddress) | 368 | DebuggerClientImpl::stack_get(int depth) |
4219 | 368 | { | 369 | { |
4220 | 369 | std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize); | 370 | std::size_t id = ++theLastId; |
4221 | 370 | if (aDatapage >= 0) | 371 | *theOutStream << "stack_get"; |
4222 | 371 | *theStream << " -p " << aDatapage; | 372 | if (depth >= 0) { |
4223 | 372 | if (aPropertyKey != "") | 373 | *theOutStream << " -d " << depth; |
4224 | 373 | *theStream << " -k " << aPropertyKey; | 374 | } |
4225 | 374 | if (aPropertyAddress != "") | 375 | *theOutStream << " -i " << id << '\0'; |
4226 | 375 | *theStream << " -a " << aPropertyAddress; | 376 | theOutStream->flush(); |
4227 | 376 | *theStream << '\0'; | 377 | return id; |
4228 | 377 | theStream->sync(); | 378 | } |
4229 | 378 | return id; | 379 | |
4230 | 379 | } | 380 | std::size_t |
4231 | 380 | 381 | DebuggerClientImpl::context_names(int depth) | |
4232 | 381 | std::size_t DebuggerClientImpl::property_x(const std::string& aCommand, | 382 | { |
4233 | 382 | const std::string& aPropertyLongName, | 383 | std::size_t id = ++theLastId; |
4234 | 383 | int aStackDepth, | 384 | *theOutStream << "context_names"; |
4235 | 384 | int aContextId, | 385 | if (depth >= 0) { |
4236 | 385 | std::size_t aMaxDataSize) | 386 | *theOutStream << " -d " << depth; |
4237 | 386 | { | 387 | } |
4238 | 387 | std::size_t id = ++theLastId; | 388 | *theOutStream << " -i " << id << '\0'; |
4239 | 388 | *theStream << aCommand << " -i " << id << " -n " << aPropertyLongName; | 389 | theOutStream->flush(); |
4240 | 389 | if (aStackDepth > 0) | 390 | return id; |
4241 | 390 | *theStream << " -d " << aStackDepth; | 391 | } |
4242 | 391 | if (aContextId > 0) | 392 | |
4243 | 392 | *theStream << " -c " << aContextId; | 393 | std::size_t |
4244 | 393 | if (aMaxDataSize > 0) | 394 | DebuggerClientImpl::context_get(int depth, int contextId) |
4245 | 394 | *theStream << " -m " << aMaxDataSize; | 395 | { |
4246 | 395 | theStream->sync(); | 396 | std::size_t id = ++theLastId; |
4247 | 396 | return id; | 397 | *theOutStream << "context_get"; |
4248 | 397 | } | 398 | if (depth >= 0) { |
4249 | 398 | 399 | *theOutStream << " -d " << depth; | |
4250 | 399 | std::size_t DebuggerClientImpl::source(std::string const &aFile, | 400 | } |
4251 | 400 | unsigned int aBeginLine, | 401 | if (contextId >= 0){ |
4252 | 401 | unsigned int aEndLine) | 402 | *theOutStream << " -c " << contextId; |
4253 | 402 | { | 403 | } |
4254 | 403 | std::size_t id = ++theLastId; | 404 | *theOutStream << " -i " << id << '\0'; |
4255 | 404 | *theStream << "source -i " << id << " -f " << aFile; | 405 | theOutStream->flush(); |
4256 | 405 | if (aBeginLine) | 406 | return id; |
4257 | 406 | *theStream << " -b " << aBeginLine; | 407 | } |
4258 | 407 | if (aEndLine) | 408 | |
4259 | 408 | *theStream << " -e " << aEndLine; | 409 | std::size_t |
4260 | 409 | *theStream << '\0'; | 410 | DebuggerClientImpl::typemap_get() |
4261 | 410 | theStream->sync(); | 411 | { |
4262 | 411 | return id; | 412 | std::size_t id = ++theLastId; |
4263 | 412 | } | 413 | *theOutStream << "typemap_get -i " << id << '\0'; |
4264 | 413 | 414 | theOutStream->flush(); | |
4265 | 414 | std::size_t DebuggerClientImpl::stream_option(OutputStream aStream, StreamBehaviour aBehaviour) | 415 | return id; |
4266 | 415 | { | 416 | } |
4267 | 416 | std::size_t id = ++theLastId; | 417 | |
4268 | 417 | switch (aStream) { | 418 | std::size_t |
4269 | 418 | case Stdout: | 419 | DebuggerClientImpl::property_get( |
4270 | 419 | *theStream << "stdout"; | 420 | const std::string& aPropertyLongName, |
4271 | 420 | break; | 421 | int aStackDepth, |
4272 | 421 | case Stderr: | 422 | int aContextId, |
4273 | 422 | *theStream << "stderr"; | 423 | std::size_t aMaxDataSize, |
4274 | 423 | break; | 424 | int aDatapage, |
4275 | 424 | case Stdin: | 425 | const std::string& aPropertyKey) |
4276 | 425 | *theStream << "stdin"; | 426 | { |
4277 | 426 | break; | 427 | std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize); |
4278 | 427 | } | 428 | if (aDatapage >= 0) |
4279 | 428 | *theStream << " -i " << id << " -c "; | 429 | *theOutStream << " -p " << aDatapage; |
4280 | 429 | switch (aBehaviour) { | 430 | if (aPropertyKey != "") |
4281 | 430 | case Disable: | 431 | *theOutStream << " -k " << aPropertyKey; |
4282 | 431 | *theStream << "0"; | 432 | *theOutStream << '\0'; |
4283 | 432 | break; | 433 | theOutStream->flush(); |
4284 | 433 | case CopyData: | 434 | return id; |
4285 | 434 | *theStream << "1"; | 435 | } |
4286 | 435 | break; | 436 | |
4287 | 436 | case Redirection: | 437 | std::size_t |
4288 | 437 | *theStream << "2"; | 438 | DebuggerClientImpl::property_set( |
4289 | 438 | break; | 439 | const std::string& aPropertyLongName, |
4290 | 439 | } | 440 | int aStackDepth, |
4291 | 440 | *theStream << '\0'; | 441 | int aContextId, |
4292 | 441 | theStream->sync(); | 442 | std::size_t aMaxDataSize, |
4293 | 442 | return id; | 443 | const std::string& aPropertyAddress) |
4294 | 443 | } | 444 | { |
4295 | 444 | 445 | std::size_t id = property_x("property_set", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize); | |
4296 | 445 | std::size_t DebuggerClientImpl::do_break() | 446 | if (aPropertyAddress != "") |
4297 | 446 | { | 447 | *theOutStream << " -a " << aPropertyAddress; |
4298 | 447 | std::size_t id = ++theLastId; | 448 | *theOutStream << '\0'; |
4299 | 448 | *theStream << "break -i " << id << '\0'; | 449 | theOutStream->flush(); |
4300 | 449 | theStream->sync(); | 450 | return id; |
4301 | 450 | return id; | 451 | } |
4302 | 451 | } | 452 | |
4303 | 452 | 453 | std::size_t | |
4304 | 453 | std::size_t DebuggerClientImpl::eval(std::string const &aExpr) | 454 | DebuggerClientImpl::property_value( |
4305 | 454 | { | 455 | const std::string& aPropertyLongName, |
4306 | 455 | std::size_t id = ++theLastId; | 456 | int aStackDepth, |
4307 | 456 | *theStream << "eval -i " << id << " -- " << encoding::Base64::encode(aExpr.c_str()) << '\0'; | 457 | int aContextId, |
4308 | 457 | theStream->sync(); | 458 | std::size_t aMaxDataSize, |
4309 | 458 | return id; | 459 | int aDatapage, |
4310 | 459 | } | 460 | const std::string& aPropertyKey, |
4311 | 460 | 461 | const std::string& aPropertyAddress) | |
4312 | 461 | void DebuggerClientImpl::quit() { | 462 | { |
4313 | 462 | theListener.stopLooping(); | 463 | std::size_t id = property_x("property_get", aPropertyLongName, aStackDepth, aContextId, aMaxDataSize); |
4314 | 463 | theListener.join(); | 464 | if (aDatapage >= 0) |
4315 | 464 | } | 465 | *theOutStream << " -p " << aDatapage; |
4316 | 465 | 466 | if (aPropertyKey != "") | |
4317 | 466 | 467 | *theOutStream << " -k " << aPropertyKey; | |
4318 | 467 | 468 | if (aPropertyAddress != "") | |
4319 | 468 | DebuggerClientImpl::~DebuggerClientImpl() | 469 | *theOutStream << " -a " << aPropertyAddress; |
4320 | 469 | { | 470 | *theOutStream << '\0'; |
4321 | 470 | if (theListener.status() == DebuggerListener::RUNNING) { | 471 | theOutStream->flush(); |
4322 | 471 | theListener.stopLooping(); | 472 | return id; |
4323 | 472 | theListener.join(); | 473 | } |
4324 | 473 | } | 474 | |
4325 | 474 | if (theSocket) { | 475 | std::size_t |
4326 | 475 | theSocket->close(); | 476 | DebuggerClientImpl::property_x( |
4327 | 476 | theSocket->cleanUp(); | 477 | const std::string& aCommand, |
4328 | 477 | delete theSocket; | 478 | const std::string& aPropertyLongName, |
4329 | 478 | } | 479 | int aStackDepth, |
4330 | 479 | if (theStream) { | 480 | int aContextId, |
4331 | 480 | theStream->sync(); | 481 | std::size_t aMaxDataSize) |
4332 | 481 | delete theStream; | 482 | { |
4333 | 482 | delete theStreamBuffer; | 483 | std::size_t id = ++theLastId; |
4334 | 483 | } | 484 | *theOutStream << aCommand << " -i " << id << " -n " << aPropertyLongName; |
4335 | 484 | } | 485 | if (aStackDepth > 0) |
4336 | 485 | } | 486 | *theOutStream << " -d " << aStackDepth; |
4337 | 487 | if (aContextId > 0) | ||
4338 | 488 | *theOutStream << " -c " << aContextId; | ||
4339 | 489 | if (aMaxDataSize > 0) | ||
4340 | 490 | *theOutStream << " -m " << aMaxDataSize; | ||
4341 | 491 | theOutStream->flush(); | ||
4342 | 492 | return id; | ||
4343 | 493 | } | ||
4344 | 494 | |||
4345 | 495 | std::size_t | ||
4346 | 496 | DebuggerClientImpl::source( | ||
4347 | 497 | std::string const &aFile, | ||
4348 | 498 | unsigned int aBeginLine, | ||
4349 | 499 | unsigned int aEndLine) | ||
4350 | 500 | { | ||
4351 | 501 | std::size_t id = ++theLastId; | ||
4352 | 502 | *theOutStream << "source -i " << id; | ||
4353 | 503 | // enable zorba extensions | ||
4354 | 504 | *theOutStream << " -z 1"; | ||
4355 | 505 | *theOutStream << " -f \"" << aFile << "\""; | ||
4356 | 506 | if (aBeginLine) | ||
4357 | 507 | *theOutStream << " -b " << aBeginLine; | ||
4358 | 508 | if (aEndLine) | ||
4359 | 509 | *theOutStream << " -e " << aEndLine; | ||
4360 | 510 | *theOutStream << '\0'; | ||
4361 | 511 | theOutStream->flush(); | ||
4362 | 512 | return id; | ||
4363 | 513 | } | ||
4364 | 514 | |||
4365 | 515 | std::size_t | ||
4366 | 516 | DebuggerClientImpl::stream_option(OutputStream aStream, StreamBehaviour aBehaviour) | ||
4367 | 517 | { | ||
4368 | 518 | std::size_t id = ++theLastId; | ||
4369 | 519 | switch (aStream) { | ||
4370 | 520 | case Stdout: | ||
4371 | 521 | *theOutStream << "stdout"; | ||
4372 | 522 | break; | ||
4373 | 523 | case Stderr: | ||
4374 | 524 | *theOutStream << "stderr"; | ||
4375 | 525 | break; | ||
4376 | 526 | case Stdin: | ||
4377 | 527 | *theOutStream << "stdin"; | ||
4378 | 528 | break; | ||
4379 | 529 | } | ||
4380 | 530 | *theOutStream << " -i " << id << " -c "; | ||
4381 | 531 | switch (aBehaviour) { | ||
4382 | 532 | case Disable: | ||
4383 | 533 | *theOutStream << "0"; | ||
4384 | 534 | break; | ||
4385 | 535 | case CopyData: | ||
4386 | 536 | *theOutStream << "1"; | ||
4387 | 537 | break; | ||
4388 | 538 | case Redirection: | ||
4389 | 539 | *theOutStream << "2"; | ||
4390 | 540 | break; | ||
4391 | 541 | } | ||
4392 | 542 | *theOutStream << '\0'; | ||
4393 | 543 | theOutStream->flush(); | ||
4394 | 544 | return id; | ||
4395 | 545 | } | ||
4396 | 546 | |||
4397 | 547 | std::size_t | ||
4398 | 548 | DebuggerClientImpl::do_break() | ||
4399 | 549 | { | ||
4400 | 550 | std::size_t id = ++theLastId; | ||
4401 | 551 | *theOutStream << "break -i " << id << '\0'; | ||
4402 | 552 | theOutStream->flush(); | ||
4403 | 553 | return id; | ||
4404 | 554 | } | ||
4405 | 555 | |||
4406 | 556 | std::size_t | ||
4407 | 557 | DebuggerClientImpl::eval(std::string const &aExpr) | ||
4408 | 558 | { | ||
4409 | 559 | std::size_t id = ++theLastId; | ||
4410 | 560 | *theOutStream << "eval -i " << id << " -- " << encoding::Base64::encode(aExpr.c_str()) << '\0'; | ||
4411 | 561 | theOutStream->flush(); | ||
4412 | 562 | return id; | ||
4413 | 563 | } | ||
4414 | 564 | |||
4415 | 565 | void | ||
4416 | 566 | DebuggerClientImpl::quit() | ||
4417 | 567 | { | ||
4418 | 568 | theListener->stopLooping(); | ||
4419 | 569 | theListener->join(); | ||
4420 | 570 | } | ||
4421 | 571 | |||
4422 | 572 | } // namespace zorba | ||
4423 | 486 | 573 | ||
4424 | === modified file 'src/debugger/debugger_clientimpl.h' | |||
4425 | --- src/debugger/debugger_clientimpl.h 2011-07-01 01:53:24 +0000 | |||
4426 | +++ src/debugger/debugger_clientimpl.h 2011-12-20 18:15:30 +0000 | |||
4427 | @@ -13,7 +13,8 @@ | |||
4428 | 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
4429 | 14 | * limitations under the License. | 14 | * limitations under the License. |
4430 | 15 | */ | 15 | */ |
4432 | 16 | #pragma once | 16 | #ifndef ZORBA_DEBUGGER_CLIENTIMPL_H |
4433 | 17 | #define ZORBA_DEBUGGER_CLIENTIMPL_H | ||
4434 | 17 | 18 | ||
4435 | 18 | #include <string> | 19 | #include <string> |
4436 | 19 | #include <zorba/debugger_client.h> | 20 | #include <zorba/debugger_client.h> |
4437 | @@ -21,7 +22,7 @@ | |||
4438 | 21 | #include "zorbautils/runnable.h" | 22 | #include "zorbautils/runnable.h" |
4439 | 22 | 23 | ||
4440 | 23 | namespace zorba { | 24 | namespace zorba { |
4442 | 24 | class socket_streambuf; | 25 | class SocketStreambuf; |
4443 | 25 | class DebuggerEventHandler; | 26 | class DebuggerEventHandler; |
4444 | 26 | class DebuggerListener; | 27 | class DebuggerListener; |
4445 | 27 | class DebuggerClientImpl; | 28 | class DebuggerClientImpl; |
4446 | @@ -48,6 +49,7 @@ | |||
4447 | 48 | public: // API | 49 | public: // API |
4448 | 49 | virtual void accept(); | 50 | virtual void accept(); |
4449 | 50 | virtual std::size_t status(); | 51 | virtual std::size_t status(); |
4450 | 52 | virtual std::size_t variables(); | ||
4451 | 51 | virtual std::size_t feature_get(const std::string& aFeatureName); | 53 | virtual std::size_t feature_get(const std::string& aFeatureName); |
4452 | 52 | virtual std::size_t feature_set(const std::string& aFeatureName, | 54 | virtual std::size_t feature_set(const std::string& aFeatureName, |
4453 | 53 | const std::string& aValue); | 55 | const std::string& aValue); |
4454 | @@ -110,12 +112,17 @@ | |||
4455 | 110 | int aContextId = -1, | 112 | int aContextId = -1, |
4456 | 111 | std::size_t aMaxDataSize = 0); | 113 | std::size_t aMaxDataSize = 0); |
4457 | 112 | private: | 114 | private: |
4462 | 113 | TCPServerSocket theServerSocket; | 115 | TCPServerSocket theServerSocket; |
4463 | 114 | TCPSocket* theSocket; | 116 | TCPSocket* theSocket; |
4464 | 115 | socket_streambuf* theStreamBuffer; | 117 | SocketStreambuf* theInStreamBuffer; |
4465 | 116 | std::iostream* theStream; | 118 | SocketStreambuf* theOutStreamBuffer; |
4466 | 119 | std::istream* theInStream; | ||
4467 | 120 | std::ostream* theOutStream; | ||
4468 | 117 | DebuggerEventHandler* theHandler; | 121 | DebuggerEventHandler* theHandler; |
4471 | 118 | DebuggerListener theListener; | 122 | DebuggerListener* theListener; |
4472 | 119 | std::size_t theLastId; | 123 | std::size_t theLastId; |
4473 | 120 | }; | 124 | }; |
4475 | 121 | } | 125 | |
4476 | 126 | } // namespace zorba | ||
4477 | 127 | |||
4478 | 128 | #endif // ZORBA_DEBUGGER_CLIENTIMPL_H | ||
4479 | 122 | 129 | ||
4480 | === modified file 'src/debugger/debugger_common.h' | |||
4481 | --- src/debugger/debugger_common.h 2011-06-22 11:19:07 +0000 | |||
4482 | +++ src/debugger/debugger_common.h 2011-12-20 18:15:30 +0000 | |||
4483 | @@ -20,22 +20,15 @@ | |||
4484 | 20 | #include "common/common.h" | 20 | #include "common/common.h" |
4485 | 21 | 21 | ||
4486 | 22 | /* Type definitions */ | 22 | /* Type definitions */ |
4487 | 23 | typedef unsigned char StepCommand; | ||
4488 | 24 | typedef unsigned char ExecutionStatus; | 23 | typedef unsigned char ExecutionStatus; |
4489 | 25 | typedef unsigned short SuspensionCause; | 24 | typedef unsigned short SuspensionCause; |
4490 | 26 | 25 | ||
4491 | 27 | /* Kind of step command */ | ||
4492 | 28 | const StepCommand STEP_INTO = 0x01; | ||
4493 | 29 | const StepCommand STEP_OUT = 0x02; | ||
4494 | 30 | const StepCommand STEP_OVER = 0x03; | ||
4495 | 31 | |||
4496 | 32 | /* Status of the engine */ | 26 | /* Status of the engine */ |
4497 | 33 | const ExecutionStatus QUERY_IDLE = 0x01; | 27 | const ExecutionStatus QUERY_IDLE = 0x01; |
4498 | 34 | const ExecutionStatus QUERY_RUNNING = 0x02; | 28 | const ExecutionStatus QUERY_RUNNING = 0x02; |
4503 | 35 | const ExecutionStatus QUERY_RESUMED = 0x03; | 29 | const ExecutionStatus QUERY_SUSPENDED = 0x03; |
4504 | 36 | const ExecutionStatus QUERY_SUSPENDED = 0x04; | 30 | const ExecutionStatus QUERY_TERMINATED = 0x04; |
4505 | 37 | const ExecutionStatus QUERY_TERMINATED = 0x05; | 31 | const ExecutionStatus QUERY_DETACHED = 0x05; |
4502 | 38 | const ExecutionStatus QUERY_DETACHED = 0x06; | ||
4506 | 39 | 32 | ||
4507 | 40 | /* Cause of the suspension of the engine */ | 33 | /* Cause of the suspension of the engine */ |
4508 | 41 | const SuspensionCause CAUSE_USER = 0x01; | 34 | const SuspensionCause CAUSE_USER = 0x01; |
4509 | 42 | 35 | ||
4510 | === modified file 'src/debugger/debugger_commons.cpp' | |||
4511 | --- src/debugger/debugger_commons.cpp 2011-06-22 11:19:07 +0000 | |||
4512 | +++ src/debugger/debugger_commons.cpp 2011-12-20 18:15:30 +0000 | |||
4513 | @@ -151,13 +151,11 @@ | |||
4514 | 151 | theBreakCondition(0), | 151 | theBreakCondition(0), |
4515 | 152 | theExecEval(false), | 152 | theExecEval(false), |
4516 | 153 | theStepping(false) | 153 | theStepping(false) |
4517 | 154 | |||
4518 | 155 | { | 154 | { |
4519 | 156 | theRuntime = NULL; | 155 | theRuntime = NULL; |
4520 | 157 | theCurrentStaticContext = NULL; | 156 | theCurrentStaticContext = NULL; |
4521 | 158 | theCurrentDynamicContext = NULL; | 157 | theCurrentDynamicContext = NULL; |
4522 | 159 | thePlanState = NULL; | 158 | thePlanState = NULL; |
4523 | 160 | theDebugIteratorState = NULL; | ||
4524 | 161 | } | 159 | } |
4525 | 162 | 160 | ||
4526 | 163 | DebuggerCommons::~DebuggerCommons() | 161 | DebuggerCommons::~DebuggerCommons() |
4527 | @@ -185,8 +183,6 @@ | |||
4528 | 185 | 183 | ||
4529 | 186 | if(ar.is_serializing_out()) | 184 | if(ar.is_serializing_out()) |
4530 | 187 | thePlanState = NULL; | 185 | thePlanState = NULL; |
4531 | 188 | if(ar.is_serializing_out()) | ||
4532 | 189 | theDebugIteratorState = NULL; | ||
4533 | 190 | ar & theEvalItem; | 186 | ar & theEvalItem; |
4534 | 191 | ar & theExecEval; | 187 | ar & theExecEval; |
4535 | 192 | ar & theStepping; | 188 | ar & theStepping; |
4536 | @@ -230,17 +226,98 @@ | |||
4537 | 230 | } | 226 | } |
4538 | 231 | 227 | ||
4539 | 232 | unsigned int | 228 | unsigned int |
4541 | 233 | DebuggerCommons::addBreakpoint(const QueryLoc& aLocation, bool aEnabled) | 229 | DebuggerCommons::addBreakpoint(String& aFileName, int aLine, bool aEnabled) |
4542 | 234 | { | 230 | { |
4544 | 235 | BreakableIdMap::iterator lIter = theBreakableIDs.find(aLocation); | 231 | QueryLoc lLocation; |
4545 | 232 | lLocation.setLineBegin(aLine); | ||
4546 | 233 | lLocation.setLineEnd(aLine); | ||
4547 | 234 | lLocation.setFilename(aFileName.c_str()); | ||
4548 | 235 | |||
4549 | 236 | // we make sure that the this location file name is aligned with the internal ones | ||
4550 | 237 | // it must have a valid URI and a scheme (file://, http://, or https://) | ||
4551 | 238 | adjustLocationFilePath(lLocation); | ||
4552 | 239 | |||
4553 | 240 | BreakableIdMap::iterator lIter = theBreakableIDs.find(lLocation); | ||
4554 | 241 | unsigned int lId; | ||
4555 | 236 | 242 | ||
4556 | 237 | if (lIter == theBreakableIDs.end()) { | 243 | if (lIter == theBreakableIDs.end()) { |
4557 | 244 | String lFileName = aFileName; | ||
4558 | 245 | // be prepared to throw an exception | ||
4559 | 238 | std::stringstream lSs; | 246 | std::stringstream lSs; |
4565 | 239 | lSs << "The breakpoint could not be set at line " << aLocation.getLineBegin() | 247 | lSs << "The breakpoint could not be set at line " << aLine |
4566 | 240 | << " in file: " << aLocation.getFilename(); | 248 | << " in file \"" << lFileName << "\""; |
4567 | 241 | throw lSs.str(); | 249 | |
4568 | 242 | } | 250 | // let us then try some search before we fail, be good to the user and help him |
4569 | 243 | unsigned int lId = lIter->second; | 251 | // 1. first we check if he sent a file URI; in this case, sorry! |
4570 | 252 | if (lFileName.find("file://") == 0) { | ||
4571 | 253 | throw lSs.str(); | ||
4572 | 254 | } | ||
4573 | 255 | |||
4574 | 256 | // now we have to normalize if we hope to find something | ||
4575 | 257 | lFileName = URIHelper::encodeFileURI(lFileName).str(); | ||
4576 | 258 | // remove the added file schema prefix | ||
4577 | 259 | // TODO: maybe there is a better way to do this encoding | ||
4578 | 260 | lFileName = lFileName.substr(8); | ||
4579 | 261 | |||
4580 | 262 | // 2. secondly we hope he gave us part of a path of a file | ||
4581 | 263 | lIter = theBreakableIDs.begin(); | ||
4582 | 264 | String::size_type lFileNameSize = lFileName.size(); | ||
4583 | 265 | std::vector<std::pair<QueryLoc, int> > lFoundBreakables; | ||
4584 | 266 | zorba::String lFirstBreakablePath; | ||
4585 | 267 | while (lIter != theBreakableIDs.end()) { | ||
4586 | 268 | // for now, only valid if on the breakable is on the same line as requested | ||
4587 | 269 | // TODO: this could be improved if the user wants to add a breakpoint to a line | ||
4588 | 270 | // INSIDE a breakable that spans over multiple lines | ||
4589 | 271 | if (lIter->second != theMainModuleBreakableId && lIter->first.getLineBegin() == aLine) { | ||
4590 | 272 | zorba::String lBreakablePath = lIter->first.getFilename().str(); | ||
4591 | 273 | |||
4592 | 274 | // dies the given string matche any part in the breakable file name? | ||
4593 | 275 | if (lBreakablePath.find(lFileName) != String::npos) { | ||
4594 | 276 | // we found the fist candidate path | ||
4595 | 277 | if (lFirstBreakablePath == "") { | ||
4596 | 278 | lFirstBreakablePath = lBreakablePath; | ||
4597 | 279 | } | ||
4598 | 280 | // but stop as soon as we are reaching a second different path (report ambiguity) | ||
4599 | 281 | else if (lFirstBreakablePath != lBreakablePath){ | ||
4600 | 282 | lSs.str(""); | ||
4601 | 283 | lSs << "The file name \"" << aFileName << "\" is ambiguous. " | ||
4602 | 284 | << "I already found two potential files to set a breakpoint in line " << aLine | ||
4603 | 285 | << ":" << std::endl << " " << lFirstBreakablePath << std::endl << " " << lBreakablePath; | ||
4604 | 286 | throw lSs.str(); | ||
4605 | 287 | } | ||
4606 | 288 | |||
4607 | 289 | // Yes! We found one! | ||
4608 | 290 | lFoundBreakables.push_back(std::pair<QueryLoc, int>(lIter->first, lIter->second)); | ||
4609 | 291 | } | ||
4610 | 292 | } | ||
4611 | 293 | lIter++; | ||
4612 | 294 | } | ||
4613 | 295 | |||
4614 | 296 | // what should I say, not a very successful search :( | ||
4615 | 297 | if (lFoundBreakables.size() == 0) { | ||
4616 | 298 | throw lSs.str(); | ||
4617 | 299 | } | ||
4618 | 300 | |||
4619 | 301 | // TODO: The best solution would be for the debugger to enable all the | ||
4620 | 302 | // matched breakables but the protocol can send back only one ID of the | ||
4621 | 303 | // breakpoint set. | ||
4622 | 304 | |||
4623 | 305 | // so we have multiple breakables, get the first in line | ||
4624 | 306 | // TODO: this does not catch multiple breakables starting in the same line | ||
4625 | 307 | // so only one will be picked (depending how the translator generated them) | ||
4626 | 308 | unsigned int lMinCol = lFoundBreakables.at(0).first.getColumnBegin(); | ||
4627 | 309 | lId = lFoundBreakables.at(0).second; | ||
4628 | 310 | for (std::size_t i = 1; i < lFoundBreakables.size(); i++) { | ||
4629 | 311 | if (lMinCol > lFoundBreakables.at(i).first.getColumnBegin()) { | ||
4630 | 312 | lId = lFoundBreakables.at(i).second; | ||
4631 | 313 | } | ||
4632 | 314 | } | ||
4633 | 315 | } | ||
4634 | 316 | else { | ||
4635 | 317 | lId = lIter->second; | ||
4636 | 318 | } | ||
4637 | 319 | |||
4638 | 320 | // now we have a breakable, so set it accordingly | ||
4639 | 244 | theBreakables[lId].setSet(true); | 321 | theBreakables[lId].setSet(true); |
4640 | 245 | theBreakables[lId].setEnabled(aEnabled); | 322 | theBreakables[lId].setEnabled(aEnabled); |
4641 | 246 | return lId; | 323 | return lId; |
4642 | @@ -253,6 +330,12 @@ | |||
4643 | 253 | return theBreakables[aId]; | 330 | return theBreakables[aId]; |
4644 | 254 | } | 331 | } |
4645 | 255 | 332 | ||
4646 | 333 | BreakableVector | ||
4647 | 334 | DebuggerCommons::getBreakpoints() | ||
4648 | 335 | { | ||
4649 | 336 | return theBreakables; | ||
4650 | 337 | } | ||
4651 | 338 | |||
4652 | 256 | void | 339 | void |
4653 | 257 | DebuggerCommons::checkBreakpoint(unsigned int aId) | 340 | DebuggerCommons::checkBreakpoint(unsigned int aId) |
4654 | 258 | { | 341 | { |
4655 | @@ -338,6 +421,7 @@ | |||
4656 | 338 | bool | 421 | bool |
4657 | 339 | DebuggerCommons::hasToBreakAt(QueryLoc aLocation) | 422 | DebuggerCommons::hasToBreakAt(QueryLoc aLocation) |
4658 | 340 | { | 423 | { |
4659 | 424 | // we make sure that this location file name is a valid URI and has a scheme (file://, http://, or https://) | ||
4660 | 341 | adjustLocationFilePath(aLocation); | 425 | adjustLocationFilePath(aLocation); |
4661 | 342 | 426 | ||
4662 | 343 | BreakableIdMap::const_iterator lIter = theBreakableIDs.find(aLocation); | 427 | BreakableIdMap::const_iterator lIter = theBreakableIDs.find(aLocation); |
4663 | @@ -449,14 +533,6 @@ | |||
4664 | 449 | ZORBA_ASSERT(thePlanState == aPlanState); | 533 | ZORBA_ASSERT(thePlanState == aPlanState); |
4665 | 450 | } | 534 | } |
4666 | 451 | 535 | ||
4667 | 452 | void | ||
4668 | 453 | DebuggerCommons::setDebugIteratorState(DebugIteratorState* aState) | ||
4669 | 454 | { | ||
4670 | 455 | theDebugIteratorState = aState; | ||
4671 | 456 | //Check postconditions | ||
4672 | 457 | ZORBA_ASSERT(theDebugIteratorState == aState); | ||
4673 | 458 | } | ||
4674 | 459 | |||
4675 | 460 | std::list<std::pair<zstring, zstring> > | 536 | std::list<std::pair<zstring, zstring> > |
4676 | 461 | DebuggerCommons::eval(const zstring& aExpr, Zorba_SerializerOptions& aSerOpts) | 537 | DebuggerCommons::eval(const zstring& aExpr, Zorba_SerializerOptions& aSerOpts) |
4677 | 462 | { | 538 | { |
4678 | @@ -511,11 +587,17 @@ | |||
4679 | 511 | } | 587 | } |
4680 | 512 | 588 | ||
4681 | 513 | void | 589 | void |
4683 | 514 | DebuggerCommons::addBreakable(Breakable& aBreakable) | 590 | DebuggerCommons::addBreakable( |
4684 | 591 | Breakable& aBreakable, | ||
4685 | 592 | bool aIsMainModuleBreakable) | ||
4686 | 515 | { | 593 | { |
4687 | 594 | // we make sure that this breakable file name is a valid URI and has a scheme (file://, http://, or https://) | ||
4688 | 516 | adjustLocationFilePath(aBreakable.getLocation()); | 595 | adjustLocationFilePath(aBreakable.getLocation()); |
4689 | 517 | 596 | ||
4690 | 518 | unsigned int lId = theBreakables.size(); | 597 | unsigned int lId = theBreakables.size(); |
4691 | 598 | if (aIsMainModuleBreakable) { | ||
4692 | 599 | theMainModuleBreakableId = lId; | ||
4693 | 600 | } | ||
4694 | 519 | theBreakables.push_back(aBreakable); | 601 | theBreakables.push_back(aBreakable); |
4695 | 520 | theBreakableIDs[aBreakable.getLocation()] = lId; | 602 | theBreakableIDs[aBreakable.getLocation()] = lId; |
4696 | 521 | } | 603 | } |
4697 | @@ -523,6 +605,9 @@ | |||
4698 | 523 | void | 605 | void |
4699 | 524 | DebuggerCommons::pushStackFrame(QueryLoc aLocation, std::string& aFunctionName) | 606 | DebuggerCommons::pushStackFrame(QueryLoc aLocation, std::string& aFunctionName) |
4700 | 525 | { | 607 | { |
4701 | 608 | // we make sure that the stack frame locations always have valid URIs and a scheme (file://, http://, or https://) | ||
4702 | 609 | adjustLocationFilePath(aLocation); | ||
4703 | 610 | |||
4704 | 526 | theStackTrace.push_back(std::pair<QueryLoc, std::string>(aLocation, aFunctionName)); | 611 | theStackTrace.push_back(std::pair<QueryLoc, std::string>(aLocation, aFunctionName)); |
4705 | 527 | } | 612 | } |
4706 | 528 | 613 | ||
4707 | @@ -541,11 +626,24 @@ | |||
4708 | 541 | void | 626 | void |
4709 | 542 | DebuggerCommons::adjustLocationFilePath(QueryLoc& aLocation) | 627 | DebuggerCommons::adjustLocationFilePath(QueryLoc& aLocation) |
4710 | 543 | { | 628 | { |
4714 | 544 | if (aLocation.getFilename().substr(0, 7) == "file://") { | 629 | zstring lOldFilename(aLocation.getFilename()); |
4715 | 545 | // adjust the file paths by removing the schema and encoding | 630 | zstring lPrefix = lOldFilename.substr(0, 7); |
4716 | 546 | zstring lOldFilename(aLocation.getFilename()); | 631 | |
4717 | 632 | if (lPrefix == "file://") { | ||
4718 | 633 | #ifdef WIN32 | ||
4719 | 634 | // decode and encode back to solve the driver column encoding: C:, D:, etc. | ||
4720 | 547 | const String lNewFilename = URIHelper::decodeFileURI(lOldFilename.str()); | 635 | const String lNewFilename = URIHelper::decodeFileURI(lOldFilename.str()); |
4722 | 548 | aLocation.setFilename(lNewFilename.str()); | 636 | const String lNewURI = URIHelper::encodeFileURI(lNewFilename); |
4723 | 637 | aLocation.setFilename(lNewURI.str()); | ||
4724 | 638 | #endif | ||
4725 | 639 | return; | ||
4726 | 640 | } | ||
4727 | 641 | |||
4728 | 642 | // just encode and assume file for non-URI locations | ||
4729 | 643 | if (lPrefix != "http://" && lPrefix != "https:/") { | ||
4730 | 644 | const String lNewURI = URIHelper::encodeFileURI(lOldFilename.str()); | ||
4731 | 645 | aLocation.setFilename(lNewURI.str()); | ||
4732 | 646 | return; | ||
4733 | 549 | } | 647 | } |
4734 | 550 | } | 648 | } |
4735 | 551 | 649 | ||
4736 | 552 | 650 | ||
4737 | === modified file 'src/debugger/debugger_commons.h' | |||
4738 | --- src/debugger/debugger_commons.h 2011-06-22 11:19:07 +0000 | |||
4739 | +++ src/debugger/debugger_commons.h 2011-12-20 18:15:30 +0000 | |||
4740 | @@ -19,14 +19,17 @@ | |||
4741 | 19 | #include <map> | 19 | #include <map> |
4742 | 20 | #include <string> | 20 | #include <string> |
4743 | 21 | 21 | ||
4744 | 22 | #include <zorba/util/uri.h> | ||
4745 | 23 | #include <zorba/zorba_string.h> | ||
4746 | 24 | |||
4747 | 22 | #include "compiler/parser/query_loc.h" | 25 | #include "compiler/parser/query_loc.h" |
4748 | 23 | #include "runtime/core/item_iterator.h" | 26 | #include "runtime/core/item_iterator.h" |
4749 | 24 | 27 | ||
4750 | 25 | #include "zorbaserialization/serialization_engine.h" | 28 | #include "zorbaserialization/serialization_engine.h" |
4751 | 26 | #include "zorbatypes/zstring.h" | 29 | #include "zorbatypes/zstring.h" |
4752 | 27 | 30 | ||
4755 | 28 | #include "debugger/debugger_common.h" | 31 | #include "debugger_common.h" |
4756 | 29 | #include "debugger/query_locationimpl.h" | 32 | #include "query_locationimpl.h" |
4757 | 30 | 33 | ||
4758 | 31 | 34 | ||
4759 | 32 | struct Zorba_SerializerOptions; | 35 | struct Zorba_SerializerOptions; |
4760 | @@ -208,16 +211,6 @@ | |||
4761 | 208 | void setPlanState(PlanState* aPlanState); | 211 | void setPlanState(PlanState* aPlanState); |
4762 | 209 | 212 | ||
4763 | 210 | /** | 213 | /** |
4764 | 211 | * @brief Sets the current debugger state. | ||
4765 | 212 | * | ||
4766 | 213 | * When the debugger suspends, it saves its state. | ||
4767 | 214 | * | ||
4768 | 215 | * @param aState a pointer to the current debugger state. | ||
4769 | 216 | * @post aState == theDebugIteratorState | ||
4770 | 217 | */ | ||
4771 | 218 | void setDebugIteratorState(DebugIteratorState* aState); | ||
4772 | 219 | |||
4773 | 220 | /** | ||
4774 | 221 | * @brief Sets a setpoint according to the step out rules. | 214 | * @brief Sets a setpoint according to the step out rules. |
4775 | 222 | * | 215 | * |
4776 | 223 | * This method sets a breakpoint according to the rules according to | 216 | * This method sets a breakpoint according to the rules according to |
4777 | @@ -245,11 +238,14 @@ | |||
4778 | 245 | public: | 238 | public: |
4779 | 246 | 239 | ||
4780 | 247 | unsigned int | 240 | unsigned int |
4782 | 248 | addBreakpoint(const QueryLoc& location, bool enabled); | 241 | addBreakpoint(String& fileName, int line, bool enabled); |
4783 | 249 | 242 | ||
4784 | 250 | Breakable | 243 | Breakable |
4785 | 251 | getBreakpoint(unsigned int id); | 244 | getBreakpoint(unsigned int id); |
4786 | 252 | 245 | ||
4787 | 246 | BreakableVector | ||
4788 | 247 | getBreakpoints(); | ||
4789 | 248 | |||
4790 | 253 | void | 249 | void |
4791 | 254 | updateBreakpoint(unsigned int id, bool enabled); | 250 | updateBreakpoint(unsigned int id, bool enabled); |
4792 | 255 | 251 | ||
4793 | @@ -336,7 +332,7 @@ | |||
4794 | 336 | std::string getFilepathOfURI(const std::string& aUri) const; | 332 | std::string getFilepathOfURI(const std::string& aUri) const; |
4795 | 337 | 333 | ||
4796 | 338 | void | 334 | void |
4798 | 339 | addBreakable(Breakable& location); | 335 | addBreakable(Breakable& location, bool isMainModuleBreakable = false); |
4799 | 340 | 336 | ||
4800 | 341 | void | 337 | void |
4801 | 342 | pushStackFrame(QueryLoc location, std::string& functionName); | 338 | pushStackFrame(QueryLoc location, std::string& functionName); |
4802 | @@ -384,10 +380,10 @@ | |||
4803 | 384 | std::vector<DebugIterator*> theIteratorStack; | 380 | std::vector<DebugIterator*> theIteratorStack; |
4804 | 385 | std::size_t theBreakCondition; | 381 | std::size_t theBreakCondition; |
4805 | 386 | PlanState* thePlanState; | 382 | PlanState* thePlanState; |
4806 | 387 | DebugIteratorState* theDebugIteratorState; | ||
4807 | 388 | store::Item_t theEvalItem; | 383 | store::Item_t theEvalItem; |
4808 | 389 | bool theExecEval; | 384 | bool theExecEval; |
4809 | 390 | bool theStepping; | 385 | bool theStepping; |
4810 | 386 | unsigned int theMainModuleBreakableId; | ||
4811 | 391 | }; | 387 | }; |
4812 | 392 | 388 | ||
4813 | 393 | } | 389 | } |
4814 | 394 | 390 | ||
4815 | === modified file 'src/debugger/debugger_communicator.cpp' | |||
4816 | --- src/debugger/debugger_communicator.cpp 2011-07-29 23:01:30 +0000 | |||
4817 | +++ src/debugger/debugger_communicator.cpp 2011-12-20 18:15:30 +0000 | |||
4818 | @@ -77,15 +77,15 @@ | |||
4819 | 77 | void | 77 | void |
4820 | 78 | DebuggerCommunicator::connect() | 78 | DebuggerCommunicator::connect() |
4821 | 79 | { | 79 | { |
4823 | 80 | for (int i = 0; i < 3 && !theSocket; i++) | 80 | for (int i = 0; i < 5 && !theSocket; i++) |
4824 | 81 | { | 81 | { |
4825 | 82 | try | 82 | try |
4826 | 83 | { | 83 | { |
4827 | 84 | // Connect to the client on the given host and port | 84 | // Connect to the client on the given host and port |
4828 | 85 | std::auto_ptr<TCPSocket> lSocket(new TCPSocket(theHost, thePort)); | 85 | std::auto_ptr<TCPSocket> lSocket(new TCPSocket(theHost, thePort)); |
4829 | 86 | theSocket = lSocket.release(); | 86 | theSocket = lSocket.release(); |
4832 | 87 | theSocketInStream = new socket_streambuf(*theSocket); | 87 | theSocketInStream = new SocketStreambuf(*theSocket); |
4833 | 88 | theSocketOutStream = new socket_streambuf(*theSocket); | 88 | theSocketOutStream = new SocketStreambuf(*theSocket); |
4834 | 89 | theCommunicatorInStream = new std::istream(theSocketInStream); | 89 | theCommunicatorInStream = new std::istream(theSocketInStream); |
4835 | 90 | theCommunicatorOutStream = new std::ostream(theSocketOutStream); | 90 | theCommunicatorOutStream = new std::ostream(theSocketOutStream); |
4836 | 91 | theResponseQueue = new ResponseQueue(theCommunicatorOutStream); | 91 | theResponseQueue = new ResponseQueue(theCommunicatorOutStream); |
4837 | 92 | 92 | ||
4838 | === modified file 'src/debugger/debugger_communicator.h' | |||
4839 | --- src/debugger/debugger_communicator.h 2011-07-01 16:07:54 +0000 | |||
4840 | +++ src/debugger/debugger_communicator.h 2011-12-20 18:15:30 +0000 | |||
4841 | @@ -28,7 +28,7 @@ | |||
4842 | 28 | namespace zorba { | 28 | namespace zorba { |
4843 | 29 | 29 | ||
4844 | 30 | class TCPSocket; | 30 | class TCPSocket; |
4846 | 31 | class socket_streambuf; | 31 | class SocketStreambuf; |
4847 | 32 | 32 | ||
4848 | 33 | class DebuggerCommunicator { | 33 | class DebuggerCommunicator { |
4849 | 34 | 34 | ||
4850 | @@ -96,13 +96,13 @@ | |||
4851 | 96 | 96 | ||
4852 | 97 | 97 | ||
4853 | 98 | TCPSocket* theSocket; | 98 | TCPSocket* theSocket; |
4856 | 99 | socket_streambuf* theSocketInStream; | 99 | SocketStreambuf* theSocketInStream; |
4857 | 100 | socket_streambuf* theSocketOutStream; | 100 | SocketStreambuf* theSocketOutStream; |
4858 | 101 | std::istream* theCommunicatorInStream; | 101 | std::istream* theCommunicatorInStream; |
4859 | 102 | std::ostream* theCommunicatorOutStream; | 102 | std::ostream* theCommunicatorOutStream; |
4860 | 103 | ResponseQueue* theResponseQueue; | 103 | ResponseQueue* theResponseQueue; |
4861 | 104 | }; | 104 | }; |
4862 | 105 | 105 | ||
4864 | 106 | }//end of namespace | 106 | } //namespace zorba |
4865 | 107 | 107 | ||
4866 | 108 | #endif // ZORBA_DEBUGGER_COMMUNICATOR_H | 108 | #endif // ZORBA_DEBUGGER_COMMUNICATOR_H |
4867 | 109 | 109 | ||
4868 | === modified file 'src/debugger/debugger_protocol.cpp' | |||
4869 | --- src/debugger/debugger_protocol.cpp 2011-06-22 11:19:07 +0000 | |||
4870 | +++ src/debugger/debugger_protocol.cpp 2011-12-20 18:15:30 +0000 | |||
4871 | @@ -28,25 +28,17 @@ | |||
4872 | 28 | DebuggerCommand::DebuggerCommand(std::string& aCommand) | 28 | DebuggerCommand::DebuggerCommand(std::string& aCommand) |
4873 | 29 | : theData() | 29 | : theData() |
4874 | 30 | { | 30 | { |
4875 | 31 | // this implements the DBGP command specification: | ||
4876 | 32 | // http://xdebug.org/docs-dbgp.php#ide-to-debugger-engine-communications | ||
4877 | 33 | |||
4878 | 34 | // the debugger client should only send space delimited command | ||
4879 | 35 | // and arguments, therefore we only check for space character | ||
4880 | 31 | std::size_t lNameEnd = aCommand.find(" "); | 36 | std::size_t lNameEnd = aCommand.find(" "); |
4881 | 37 | |||
4882 | 38 | // first whitespace delimited token is the command name | ||
4883 | 32 | theName = aCommand.substr(0, lNameEnd); | 39 | theName = aCommand.substr(0, lNameEnd); |
4884 | 33 | std::size_t lDataBegin = aCommand.find("--", lNameEnd); | ||
4885 | 34 | std::string lArgs = aCommand.substr(lNameEnd + 1, lDataBegin); | ||
4886 | 35 | 40 | ||
4901 | 36 | if (lDataBegin != std::string::npos) { | 41 | std::string lArgs = aCommand.substr(lNameEnd + 1); |
4888 | 37 | lDataBegin += 2; | ||
4889 | 38 | while (lDataBegin < aCommand.size()) { | ||
4890 | 39 | switch (aCommand.at(lDataBegin)) { | ||
4891 | 40 | case ' ': | ||
4892 | 41 | case '\t': | ||
4893 | 42 | ++lDataBegin; | ||
4894 | 43 | continue; | ||
4895 | 44 | default: | ||
4896 | 45 | theData = aCommand.substr(lDataBegin); | ||
4897 | 46 | lDataBegin = aCommand.size(); | ||
4898 | 47 | } | ||
4899 | 48 | } | ||
4900 | 49 | } | ||
4902 | 50 | 42 | ||
4903 | 51 | bool lFollowsArg = true; | 43 | bool lFollowsArg = true; |
4904 | 52 | bool lInArgName = false; | 44 | bool lInArgName = false; |
4905 | @@ -74,6 +66,26 @@ | |||
4906 | 74 | lInArgName = true; | 66 | lInArgName = true; |
4907 | 75 | continue; | 67 | continue; |
4908 | 76 | } | 68 | } |
4909 | 69 | // we found the encoded data in this message | ||
4910 | 70 | if (lArgName.str() == "") { | ||
4911 | 71 | // DBGP is fuzzy here: can there be whitespaces between "--" and the encoded data? | ||
4912 | 72 | // so, tollerate the whitespaces before data starts | ||
4913 | 73 | std::string::size_type lDataBegin = i + 1; | ||
4914 | 74 | while (++i < lArgs.size()) { | ||
4915 | 75 | switch (lArgs.at(i)) { | ||
4916 | 76 | case ' ': | ||
4917 | 77 | case '\t': | ||
4918 | 78 | continue; | ||
4919 | 79 | default: | ||
4920 | 80 | lDataBegin = i; | ||
4921 | 81 | // force the while to terminate | ||
4922 | 82 | i = lArgs.size(); | ||
4923 | 83 | } | ||
4924 | 84 | } | ||
4925 | 85 | |||
4926 | 86 | theData = lArgs.substr(lDataBegin); | ||
4927 | 87 | } | ||
4928 | 88 | |||
4929 | 77 | default: | 89 | default: |
4930 | 78 | if (!lInArgName) { | 90 | if (!lInArgName) { |
4931 | 79 | throw "error reading command"; | 91 | throw "error reading command"; |
4932 | 80 | 92 | ||
4933 | === modified file 'src/debugger/debugger_runtime.cpp' | |||
4934 | --- src/debugger/debugger_runtime.cpp 2011-08-03 02:26:53 +0000 | |||
4935 | +++ src/debugger/debugger_runtime.cpp 2011-12-20 18:15:30 +0000 | |||
4936 | @@ -21,6 +21,7 @@ | |||
4937 | 21 | #include <memory> | 21 | #include <memory> |
4938 | 22 | #include <vector> | 22 | #include <vector> |
4939 | 23 | #include <sstream> | 23 | #include <sstream> |
4940 | 24 | #include <iomanip> | ||
4941 | 24 | #include <fstream> | 25 | #include <fstream> |
4942 | 25 | 26 | ||
4943 | 26 | #include <zorba/util/uri.h> | 27 | #include <zorba/util/uri.h> |
4944 | @@ -70,7 +71,8 @@ | |||
4945 | 70 | thePlanIsOpen(false), | 71 | thePlanIsOpen(false), |
4946 | 71 | theSerializer(0), | 72 | theSerializer(0), |
4947 | 72 | theItemHandler(aHandler), | 73 | theItemHandler(aHandler), |
4949 | 73 | theCallbackData(aCallBackData) | 74 | theCallbackData(aCallBackData), |
4950 | 75 | theLastContinuationCommand() | ||
4951 | 74 | { | 76 | { |
4952 | 75 | } | 77 | } |
4953 | 76 | 78 | ||
4954 | @@ -122,7 +124,7 @@ | |||
4955 | 122 | DebuggerRuntime::runQuery() | 124 | DebuggerRuntime::runQuery() |
4956 | 123 | { | 125 | { |
4957 | 124 | theLock.wlock(); | 126 | theLock.wlock(); |
4959 | 125 | theExecStatus = theExecStatus == QUERY_SUSPENDED ? QUERY_RESUMED : QUERY_RUNNING; | 127 | theExecStatus = QUERY_RUNNING; |
4960 | 126 | 128 | ||
4961 | 127 | try { | 129 | try { |
4962 | 128 | DebuggerCommons* lCommons = getDebbugerCommons(); | 130 | DebuggerCommons* lCommons = getDebbugerCommons(); |
4963 | @@ -144,33 +146,23 @@ | |||
4964 | 144 | theOStream.flush(); | 146 | theOStream.flush(); |
4965 | 145 | } catch (FlowCtlException&) { | 147 | } catch (FlowCtlException&) { |
4966 | 146 | // Runtime correctly terminated by user interrupt | 148 | // Runtime correctly terminated by user interrupt |
4970 | 147 | } catch (ZorbaException const& e){ | 149 | } catch (ZorbaException const& e) { |
4971 | 148 | // this does not rethrow but only print the error message | 150 | std::cerr << e << std::endl; |
4969 | 149 | ZorbaImpl::notifyError(theQuery->theDiagnosticHandler, e); | ||
4972 | 150 | } | 151 | } |
4973 | 151 | theLock.wlock(); | 152 | theLock.wlock(); |
4974 | 152 | theExecStatus = QUERY_TERMINATED; | 153 | theExecStatus = QUERY_TERMINATED; |
4975 | 153 | theLock.unlock(); | 154 | theLock.unlock(); |
4976 | 154 | } | 155 | } |
4977 | 155 | 156 | ||
4978 | 156 | |||
4979 | 157 | void | ||
4980 | 158 | DebuggerRuntime::setQueryRunning() | ||
4981 | 159 | { | ||
4982 | 160 | AutoLock lLock(theLock, Lock::WRITE); | ||
4983 | 161 | assert(theExecStatus == QUERY_RESUMED); | ||
4984 | 162 | theExecStatus = QUERY_RUNNING; | ||
4985 | 163 | } | ||
4986 | 164 | |||
4987 | 165 | // **************************************************************************** | 157 | // **************************************************************************** |
4988 | 166 | // Breakpoints | 158 | // Breakpoints |
4989 | 167 | 159 | ||
4990 | 168 | unsigned int | 160 | unsigned int |
4992 | 169 | DebuggerRuntime::addBreakpoint(const QueryLoc& aLocation, bool aEnabled) | 161 | DebuggerRuntime::addBreakpoint(String& aFileName, int aLine, bool aEnabled) |
4993 | 170 | { | 162 | { |
4994 | 171 | AutoLock lLock(theLock, Lock::WRITE); | 163 | AutoLock lLock(theLock, Lock::WRITE); |
4995 | 172 | DebuggerCommons* lCommons = getDebbugerCommons(); | 164 | DebuggerCommons* lCommons = getDebbugerCommons(); |
4997 | 173 | return lCommons->addBreakpoint(aLocation, aEnabled); | 165 | return lCommons->addBreakpoint(aFileName, aLine, aEnabled); |
4998 | 174 | } | 166 | } |
4999 | 175 | 167 | ||
5000 | 176 | Breakable | 168 | Breakable |
I reviewed CMakeConfigurat ion.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.