3 * wxbDataParser, class that receives and analyses data
5 * Nicolas Boichat, April-July 2004
10 Copyright (C) 2004-2006 Kern Sibbald
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 version 2 as amended with additional clauses defined in the
15 file LICENSE in the main source directory.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 the file LICENSE for additional details.
30 #include "wxbmainframe.h"
34 #include "wxbtableparser.h"
36 /* A macro named Yield is defined under MinGW */
39 bool wxbUtils::inited = false;
41 wxString wxbUtils::ConvertToPrintable(wxString& str) {
42 /* FIXME : Unicode support should be added to fix this problem */
43 #if (wxUSE_UNICODE == 0) && __WXGTK20__
45 /* Convert the string to something printable without unicode */
46 for (unsigned int i = 0; i < strnew.Length(); i++) {
47 /* If the character is not ASCII, print a ? */
48 if (((unsigned char)strnew[i] > (unsigned char)127)) {
58 /* Sleeps during milliseconds (wrapper for wxUsleep (2.4) or wxMilliSleep (2.6)) */
59 void wxbUtils::MilliSleep(unsigned long milliseconds) {
60 #if wxCHECK_VERSION(2, 6, 0)
61 ::wxMilliSleep(milliseconds);
63 ::wxUsleep(milliseconds);
68 void wxbUtils::Init() {
73 void wxbUtils::Reset() {
77 /* Parse a table in tableParser */
78 wxbTableParser* wxbUtils::CreateAndWaitForParser(wxString cmd) {
79 wxbTableParser* tableParser = new wxbTableParser();
81 wxbMainFrame::GetInstance()->Send(cmd);
83 //time_t base = wxDateTime::Now().GetTicks();
84 while (!tableParser->hasFinished()) {
85 //innerThread->Yield();
86 wxTheApp->Yield(true);
87 wxbUtils::MilliSleep(100);
88 //if (base+15 < wxDateTime::Now().GetTicks()) break;
93 /* Run a command, and waits until prompt result is fully received,
94 * if keepresults is true, returns a valid pointer to a wxbPromptParser
95 * containing the data. */
96 wxbPromptParser* wxbUtils::WaitForPrompt(wxString cmd, bool keepresults) {
97 wxbPromptParser* promptParser = new wxbPromptParser();
99 wxbMainFrame::GetInstance()->Send(cmd);
101 //time_t base = wxDateTime::Now().GetTicks();
102 while (!promptParser->hasFinished()) {
103 //innerThread->Yield();
104 wxTheApp->Yield(true);
105 wxbUtils::MilliSleep(100);
106 //if (base+15 < wxDateTime::Now().GetTicks()) break;
118 /* Run a command, and waits until result is fully received. */
119 wxbDataTokenizer* wxbUtils::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
120 wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
122 wxbMainFrame::GetInstance()->Send(cmd);
124 //wxbMainFrame::GetInstance()->Print("(<WFE)", CS_DEBUG);
126 //time_t base = wxDateTime::Now().GetTicks();
127 while (!datatokenizer->hasFinished()) {
128 //innerThread->Yield();
129 wxTheApp->Yield(true);
130 wxbUtils::MilliSleep(100);
131 //if (base+15 < wxDateTime::Now().GetTicks()) break;
134 //wxbMainFrame::GetInstance()->Print("(>WFE)", CS_DEBUG);
137 return datatokenizer;
140 delete datatokenizer;
146 /* Creates a new wxbDataParser, and register it in wxbMainFrame */
147 wxbDataParser::wxbDataParser(bool lineanalysis) {
148 wxbMainFrame::GetInstance()->Register(this);
149 this->lineanalysis = lineanalysis;
153 /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
154 wxbDataParser::~wxbDataParser() {
155 wxbMainFrame::GetInstance()->Unregister(this);
159 * Receives director information, forwarded by wxbMainFrame, and sends it
160 * line by line to the virtual function Analyse.
162 bool wxbDataParser::Print(wxString str, int status) {
165 bool allnewline = true;
166 for (unsigned int i = 0; i < str.Length(); i++) {
167 if (!(allnewline = (str.GetChar(i) == '\n')))
172 ret = Analyse(buffer << wxT("\n"), CS_DATA);
174 for (unsigned int i = 1; i < str.Length(); i++) {
175 ret = Analyse(wxT("\n"), status);
179 wxStringTokenizer tkz(str, wxT("\n"),
180 (wxStringTokenizerMode)(wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL));
182 while ( tkz.HasMoreTokens() ) {
183 buffer << tkz.GetNextToken();
184 if (buffer.Length() != 0) {
185 if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
186 (buffer.GetChar(buffer.Length()-1) == '\r')) {
187 ret = Analyse(buffer, status);
194 if (buffer == wxT("$ ")) { // Restore console
195 ret = Analyse(buffer, status);
199 if (status != CS_DATA) {
200 if (buffer.Length() != 0) {
201 ret = Analyse(buffer, CS_DATA);
204 ret = Analyse(wxT(""), status);
208 ret = Analyse(wxString(str), status);
213 /* Creates a new wxbDataTokenizer */
214 wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
218 /* Destroy a wxbDataTokenizer */
219 wxbDataTokenizer::~wxbDataTokenizer() {
224 * Receives director information, forwarded by wxbMainFrame.
226 bool wxbDataTokenizer::Analyse(wxString str, int status) {
227 finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
229 if (str != wxT("")) {
235 /* Returns true if the last signal received was an end signal,
236 * indicating that no more data is available */
237 bool wxbDataTokenizer::hasFinished() {
241 /* Creates a new wxbDataTokenizer */
242 wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
248 questionStr = wxT("");
251 /* Destroy a wxbDataTokenizer */
252 wxbPromptParser::~wxbPromptParser() {
259 * Receives director information, forwarded by wxbMainFrame.
261 bool wxbPromptParser::Analyse(wxString str, int status) {
262 if (status == CS_DATA) {
263 if (finished || prompt) { /* New question */
271 questionStr = wxT("");
277 if (((i = str.Find(wxT(": "))) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
279 choices = new wxArrayString();
280 choices->Add(wxT("")); /* index 0 is never used by multiple choice questions */
284 if ((long)choices->GetCount() != num) { /* new choice has begun */
286 choices = new wxArrayString();
287 choices->Add(wxT(""), num); /* fill until this number */
291 choices->Add(str.Mid(i+2).RemoveLast());
293 else if (!choices) { /* Introduction, no list received yet */
294 introStr << questionStr;
295 questionStr = wxString(str);
297 else { /* List receveived, get the question now */
298 introStr << questionStr;
299 questionStr = wxString(str);
303 finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
304 if (prompt = ((status == CS_PROMPT) && (questionStr != wxT("$ ")))) { // && (str.Find(": ") == str.Length())
305 if (introStr.Last() == '\n') {
306 introStr.RemoveLast();
308 if ((introStr != wxT("")) && (questionStr == wxT(""))) {
309 questionStr = introStr;
313 if ((!choices) && (questionStr.Find(wxT("(yes/mod/no)")) > -1)) {
314 choices = new wxArrayString();
315 choices->Add(wxT("yes"));
316 choices->Add(wxT("mod"));
317 choices->Add(wxT("no"));
323 else { /* ended or (dis)connected */
329 questionStr = wxT("");
336 /* Returns true if the last signal received was an prompt signal,
337 * indicating that the answer must be sent */
338 bool wxbPromptParser::hasFinished() {
342 /* Returns true if the last message received is a prompt message */
343 bool wxbPromptParser::isPrompt() {
347 /* Returns multiple choice question's introduction */
348 wxString wxbPromptParser::getIntroString() {
352 /* Returns question string */
353 wxString wxbPromptParser::getQuestionString() {
357 /* Returns a wxArrayString containing the indexed choices we have
358 * to answer the question, or NULL if this question is not a multiple
360 wxArrayString* wxbPromptParser::getChoices() {
364 /* Returns true if the expected answer to the choice list is a number,
365 * false if it is a string (for example yes/mod/no). */
366 bool wxbPromptParser::isNumericalChoice() {