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