]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/wx-console/wxbutils.cpp
- wxbRestorePanel : implemented restore before=<Date> parameter.
[bacula/bacula] / bacula / src / wx-console / wxbutils.cpp
1 /*
2  *
3  *   wxbDataParser, class that receives and analyses data
4  *
5  *    Nicolas Boichat, April-July 2004
6  *
7  *    Version $Id$
8  */
9 /*
10    Copyright (C) 2004 Kern Sibbald and John Walker
11
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    as published by the Free Software Foundation; either version 2
15    of the License, or (at your option) any later version.
16
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    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26  
27 #include "wxbutils.h"
28
29 #include "wxbmainframe.h"
30
31 #include "csprint.h"
32
33 #include "wxbtableparser.h"
34
35 /* A macro named Yield is defined under MinGW */
36 #undef Yield
37
38 bool wxbUtils::inited = false;
39
40 /* Initialization */
41 void wxbUtils::Init() {
42    inited = true;
43 }
44
45 /* Reset state */
46 void wxbUtils::Reset() {
47    inited = false;
48 }
49
50 /* Parse a table in tableParser */
51 wxbTableParser* wxbUtils::CreateAndWaitForParser(wxString cmd) {
52    wxbTableParser* tableParser = new wxbTableParser();
53
54    wxbMainFrame::GetInstance()->Send(cmd);
55
56    //time_t base = wxDateTime::Now().GetTicks();
57    while (!tableParser->hasFinished()) {
58       //innerThread->Yield();
59       wxTheApp->Yield(true);
60       ::wxUsleep(100);
61       //if (base+15 < wxDateTime::Now().GetTicks()) break;
62    }
63    return tableParser;
64 }
65
66 /* Run a command, and waits until prompt result is fully received,
67  * if keepresults is true, returns a valid pointer to a wxbPromptParser
68  * containing the data. */
69 wxbPromptParser* wxbUtils::WaitForPrompt(wxString cmd, bool keepresults) {
70    wxbPromptParser* promptParser = new wxbPromptParser();
71    
72    wxbMainFrame::GetInstance()->Send(cmd);
73     
74    //time_t base = wxDateTime::Now().GetTicks();
75    while (!promptParser->hasFinished()) {
76       //innerThread->Yield();
77       wxTheApp->Yield(true);
78       ::wxUsleep(100);
79       //if (base+15 < wxDateTime::Now().GetTicks()) break;
80    }
81      
82    if (keepresults) {
83       return promptParser;
84    }
85    else {
86       delete promptParser;
87       return NULL;
88    }  
89 }
90
91 /* Run a command, and waits until result is fully received. */
92 wxbDataTokenizer* wxbUtils::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
93    wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
94
95    wxbMainFrame::GetInstance()->Send(cmd);
96    
97    //wxbMainFrame::GetInstance()->Print("(<WFE)", CS_DEBUG);
98    
99    //time_t base = wxDateTime::Now().GetTicks();
100    while (!datatokenizer->hasFinished()) {
101       //innerThread->Yield();
102       wxTheApp->Yield(true);
103       ::wxUsleep(100);
104       //if (base+15 < wxDateTime::Now().GetTicks()) break;
105    }
106    
107    //wxbMainFrame::GetInstance()->Print("(>WFE)", CS_DEBUG);
108    
109    if (keepresults) {
110       return datatokenizer;
111    }
112    else {
113       delete datatokenizer;
114       return NULL;
115    }
116 }
117
118
119 /* Creates a new wxbDataParser, and register it in wxbMainFrame */
120 wxbDataParser::wxbDataParser(bool lineanalysis) {
121    wxbMainFrame::GetInstance()->Register(this);
122    this->lineanalysis = lineanalysis;
123 //   buffer = "";
124 }
125
126 /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
127 wxbDataParser::~wxbDataParser() {
128    wxbMainFrame::GetInstance()->Unregister(this);
129 }
130
131 /*
132  * Receives director information, forwarded by wxbMainFrame, and sends it
133  * line by line to the virtual function Analyse.
134  */
135 bool wxbDataParser::Print(wxString str, int status) {
136    bool ret = false;
137    if (lineanalysis) {
138       bool allnewline = true;
139       for (unsigned int i = 0; i < str.Length(); i++) {
140          if (!(allnewline = (str.GetChar(i) == '\n')))
141             break;
142       }
143    
144       if (allnewline) {
145          ret = Analyse(buffer << "\n", CS_DATA);
146          buffer = "";
147          for (unsigned int i = 1; i < str.Length(); i++) {
148             ret = Analyse("\n", status);
149          }
150       }
151       else {
152          wxStringTokenizer tkz(str, "\n", 
153             (wxStringTokenizerMode)(wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL));
154    
155          while ( tkz.HasMoreTokens() ) {
156             buffer << tkz.GetNextToken();
157             if (buffer.Length() != 0) {
158                if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
159                   (buffer.GetChar(buffer.Length()-1) == '\r')) {
160                   ret = Analyse(buffer, status);
161                   buffer = "";
162                }
163             }
164          }
165       }
166    
167       if (buffer == "$ ") { // Restore console
168          ret = Analyse(buffer, status);
169          buffer = "";
170       }
171    
172       if (status != CS_DATA) {
173          if (buffer.Length() != 0) {
174             ret = Analyse(buffer, CS_DATA);
175          }
176          buffer = "";
177          ret = Analyse("", status);
178       }
179    }
180    else {
181       ret = Analyse(wxString(str), status);
182    }
183    return ret;
184 }
185
186 /* Creates a new wxbDataTokenizer */
187 wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
188    finished = false;
189 }
190
191 /* Destroy a wxbDataTokenizer */
192 wxbDataTokenizer::~wxbDataTokenizer() {
193
194 }
195
196 /*
197  *   Receives director information, forwarded by wxbMainFrame.
198  */
199 bool wxbDataTokenizer::Analyse(wxString str, int status) {
200    finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
201
202    if (str != "") {
203       Add(str);
204    }
205    return false;
206 }
207
208 /* Returns true if the last signal received was an end signal, 
209  * indicating that no more data is available */
210 bool wxbDataTokenizer::hasFinished() {
211    return finished;
212 }
213
214 /* Creates a new wxbDataTokenizer */
215 wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
216    finished = false;
217    prompt = false;
218    introStr = "";
219    choices = NULL;
220    numerical = false;
221    questionStr = "";
222 }
223
224 /* Destroy a wxbDataTokenizer */
225 wxbPromptParser::~wxbPromptParser() {
226    if (choices) {
227       delete choices;
228    }
229 }
230
231 /*
232  *   Receives director information, forwarded by wxbMainFrame.
233  */
234 bool wxbPromptParser::Analyse(wxString str, int status) {
235    if (status == CS_DATA) {
236       if (finished || prompt) { /* New question */
237          finished = false;
238          prompt = false;
239          if (choices) {
240             delete choices;
241             choices = NULL;
242             numerical = false;
243          }
244          questionStr = "";
245          introStr = "";
246       }
247       int i;
248       long num;
249       
250       if (((i = str.Find(": ")) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
251          if (!choices) {
252             choices = new wxArrayString();
253             choices->Add(""); /* index 0 is never used by multiple choice questions */
254             numerical = true;
255          }
256          
257          if ((long)choices->GetCount() != num) { /* new choice has begun */
258             delete choices;
259             choices = new wxArrayString();
260             choices->Add("", num); /* fill until this number */
261             numerical = true;
262          }
263          
264          choices->Add(str.Mid(i+2).RemoveLast());
265       }
266       else if (!choices) { /* Introduction, no list received yet */
267          introStr << questionStr;
268          questionStr = wxString(str);
269       }
270       else { /* List receveived, get the question now */
271          introStr << questionStr;
272          questionStr = wxString(str);
273       }
274    }
275    else {
276       finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
277       if (prompt = ((status == CS_PROMPT) && (questionStr != "$ "))) { // && (str.Find(": ") == str.Length())
278          if (introStr.Last() == '\n') {
279             introStr.RemoveLast();
280          }
281          if ((introStr != "") && (questionStr == "")) {
282             questionStr = introStr;
283             introStr = "";
284          }
285          
286          if ((!choices) && (questionStr.Find("(yes/mod/no)") > -1)) {
287             choices = new wxArrayString();
288             choices->Add("yes");
289             choices->Add("mod");
290             choices->Add("no");
291             numerical = false;
292          }
293          
294          return true;
295       }
296       else { /* ended or (dis)connected */
297          if (choices) {
298             delete choices;
299             choices = NULL;
300             numerical = false;
301          }
302          questionStr = "";
303          introStr = "";
304       }
305    }
306    return false;
307 }
308
309 /* Returns true if the last signal received was an prompt signal, 
310  * indicating that the answer must be sent */
311 bool wxbPromptParser::hasFinished() {
312    return finished;
313 }
314
315 /* Returns true if the last message received is a prompt message */
316 bool wxbPromptParser::isPrompt() {
317    return prompt;
318 }
319
320 /* Returns multiple choice question's introduction */
321 wxString wxbPromptParser::getIntroString() {
322    return introStr;
323 }
324
325 /* Returns question string */
326 wxString wxbPromptParser::getQuestionString() {
327    return questionStr;
328 }
329
330 /* Returns a wxArrayString containing the indexed choices we have
331  * to answer the question, or NULL if this question is not a multiple
332  * choice one. */
333 wxArrayString* wxbPromptParser::getChoices() {
334    return choices;
335 }
336
337 /* Returns true if the expected answer to the choice list is a number,
338  * false if it is a string (for example yes/mod/no). */
339 bool wxbPromptParser::isNumericalChoice() {
340    return numerical;
341 }