]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/wx-console/wxbutils.cpp
kes Fix code to check for two resources of same name. It forgot
[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    Bacula® - The Network Backup Solution
11
12    Copyright (C) 2004-2006 Free Software Foundation Europe e.V.
13
14    The main author of Bacula is Kern Sibbald, with contributions from
15    many others, a complete list can be found in the file AUTHORS.
16    This program is Free Software; you can redistribute it and/or
17    modify it under the terms of version two of the GNU General Public
18    License as published by the Free Software Foundation plus additions
19    that are listed in the file LICENSE.
20
21    This program is distributed in the hope that it will be useful, but
22    WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24    General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program; if not, write to the Free Software
28    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29    02110-1301, USA.
30
31    Bacula® is a registered trademark of John Walker.
32    The licensor of Bacula is the Free Software Foundation Europe
33    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34    Switzerland, email:ftf@fsfeurope.org.
35 */
36
37 /*  Windows debug builds set _DEBUG which is used by wxWidgets to select their
38  *  debug memory allocator.  Unfortunately it conflicts with Bacula's SmartAlloc.
39  * So we turn _DEBUG off since we aren't interested in things it enables.
40  */
41
42 #undef _DEBUG
43
44 #include "bacula.h"
45
46 #include "wxbutils.h"
47
48 #include "wxbmainframe.h"
49
50 #include "csprint.h"
51
52 #include "wxbtableparser.h"
53
54 /* A macro named Yield is defined under MinGW */
55 #undef Yield
56
57 bool wxbUtils::inited = false;
58
59 wxString wxbUtils::ConvertToPrintable(wxString& str) {
60    /* FIXME : Unicode support should be added to fix this problem */
61 #if (wxUSE_UNICODE == 0) && __WXGTK20__
62    wxString strnew(str);
63    /* Convert the string to something printable without unicode */
64    for (unsigned int i = 0; i < strnew.Length(); i++) {
65       /* If the character is not ASCII, print a ? */
66       if (((unsigned char)strnew[i] > (unsigned char)127)) {
67          strnew[i] = '?';
68       }
69    }
70    return strnew;
71 #else
72    return str;
73 #endif   
74 }
75
76 /* Sleeps during milliseconds (wrapper for wxUsleep (2.4) or wxMilliSleep (2.6)) */
77 void wxbUtils::MilliSleep(unsigned long milliseconds) {
78 #if wxCHECK_VERSION(2, 6, 0)
79    ::wxMilliSleep(milliseconds);
80 #else
81    ::wxUsleep(milliseconds);
82 #endif
83 }
84
85 /* Initialization */
86 void wxbUtils::Init() {
87    inited = true;
88 }
89
90 /* Reset state */
91 void wxbUtils::Reset() {
92    inited = false;
93 }
94
95 /* Parse a table in tableParser */
96 wxbTableParser* wxbUtils::CreateAndWaitForParser(wxString cmd) {
97    wxbTableParser* tableParser = new wxbTableParser();
98
99    wxbMainFrame::GetInstance()->Send(cmd);
100
101    //time_t base = wxDateTime::Now().GetTicks();
102    while (!tableParser->hasFinished()) {
103       //innerThread->Yield();
104       wxTheApp->Yield(true);
105       wxbUtils::MilliSleep(100);
106       //if (base+15 < wxDateTime::Now().GetTicks()) break;
107    }
108    return tableParser;
109 }
110
111 /* Run a command, and waits until prompt result is fully received,
112  * if keepresults is true, returns a valid pointer to a wxbPromptParser
113  * containing the data. */
114 wxbPromptParser* wxbUtils::WaitForPrompt(wxString cmd, bool keepresults) {
115    wxbPromptParser* promptParser = new wxbPromptParser();
116    
117    wxbMainFrame::GetInstance()->Send(cmd);
118     
119    //time_t base = wxDateTime::Now().GetTicks();
120    while (!promptParser->hasFinished()) {
121       //innerThread->Yield();
122       wxTheApp->Yield(true);
123       wxbUtils::MilliSleep(100);
124       //if (base+15 < wxDateTime::Now().GetTicks()) break;
125    }
126      
127    if (keepresults) {
128       return promptParser;
129    }
130    else {
131       delete promptParser;
132       return NULL;
133    }  
134 }
135
136 /* Run a command, and waits until result is fully received. */
137 wxbDataTokenizer* wxbUtils::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
138    wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
139
140    wxbMainFrame::GetInstance()->Send(cmd);
141    
142    //wxbMainFrame::GetInstance()->Print("(<WFE)", CS_DEBUG);
143    
144    //time_t base = wxDateTime::Now().GetTicks();
145    while (!datatokenizer->hasFinished()) {
146       //innerThread->Yield();
147       wxTheApp->Yield(true);
148       wxbUtils::MilliSleep(100);
149       //if (base+15 < wxDateTime::Now().GetTicks()) break;
150    }
151    
152    //wxbMainFrame::GetInstance()->Print("(>WFE)", CS_DEBUG);
153    
154    if (keepresults) {
155       return datatokenizer;
156    }
157    else {
158       delete datatokenizer;
159       return NULL;
160    }
161 }
162
163
164 /* Creates a new wxbDataParser, and register it in wxbMainFrame */
165 wxbDataParser::wxbDataParser(bool lineanalysis) {
166    wxbMainFrame::GetInstance()->Register(this);
167    this->lineanalysis = lineanalysis;
168 //   buffer = "";
169 }
170
171 /* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
172 wxbDataParser::~wxbDataParser() {
173    wxbMainFrame::GetInstance()->Unregister(this);
174 }
175
176 /*
177  * Receives director information, forwarded by wxbMainFrame, and sends it
178  * line by line to the virtual function Analyse.
179  */
180 bool wxbDataParser::Print(wxString str, int status) {
181    bool ret = false;
182    if (lineanalysis) {
183       bool allnewline = true;
184       for (unsigned int i = 0; i < str.Length(); i++) {
185          if (!(allnewline = (str.GetChar(i) == '\n')))
186             break;
187       }
188    
189       if (allnewline) {
190          ret = Analyse(buffer << wxT("\n"), CS_DATA);
191          buffer = wxT("");
192          for (unsigned int i = 1; i < str.Length(); i++) {
193             ret = Analyse(wxT("\n"), status);
194          }
195       }
196       else {
197          wxStringTokenizer tkz(str, wxT("\n"), 
198             (wxStringTokenizerMode)(wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL));
199    
200          while ( tkz.HasMoreTokens() ) {
201             buffer << tkz.GetNextToken();
202             if (buffer.Length() != 0) {
203                if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
204                   (buffer.GetChar(buffer.Length()-1) == '\r')) {
205                   ret = Analyse(buffer, status);
206                   buffer = wxT("");
207                }
208             }
209          }
210       }
211    
212       if (buffer == wxT("$ ")) { // Restore console
213          ret = Analyse(buffer, status);
214          buffer = wxT("");
215       }
216    
217       if (status != CS_DATA) {
218          if (buffer.Length() != 0) {
219             ret = Analyse(buffer, CS_DATA);
220          }
221          buffer = wxT("");
222          ret = Analyse(wxT(""), status);
223       }
224    }
225    else {
226       ret = Analyse(wxString(str), status);
227    }
228    return ret;
229 }
230
231 /* Creates a new wxbDataTokenizer */
232 wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
233    finished = false;
234 }
235
236 /* Destroy a wxbDataTokenizer */
237 wxbDataTokenizer::~wxbDataTokenizer() {
238
239 }
240
241 /*
242  *   Receives director information, forwarded by wxbMainFrame.
243  */
244 bool wxbDataTokenizer::Analyse(wxString str, int status) {
245    finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
246
247    if (str != wxT("")) {
248       Add(str);
249    }
250    return false;
251 }
252
253 /* Returns true if the last signal received was an end signal, 
254  * indicating that no more data is available */
255 bool wxbDataTokenizer::hasFinished() {
256    return finished;
257 }
258
259 /* Creates a new wxbDataTokenizer */
260 wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
261    finished = false;
262    prompt = false;
263    introStr = wxT("");
264    choices = NULL;
265    numerical = false;
266    questionStr = wxT("");
267 }
268
269 /* Destroy a wxbDataTokenizer */
270 wxbPromptParser::~wxbPromptParser() {
271    if (choices) {
272       delete choices;
273    }
274 }
275
276 /*
277  *   Receives director information, forwarded by wxbMainFrame.
278  */
279 bool wxbPromptParser::Analyse(wxString str, int status) {
280    if (status == CS_DATA) {
281       if (finished || prompt) { /* New question */
282          finished = false;
283          prompt = false;
284          if (choices) {
285             delete choices;
286             choices = NULL;
287             numerical = false;
288          }
289          questionStr = wxT("");
290          introStr = wxT("");
291       }
292       int i;
293       long num;
294       
295       if (((i = str.Find(wxT(": "))) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
296          if (!choices) {
297             choices = new wxArrayString();
298             choices->Add(wxT("")); /* index 0 is never used by multiple choice questions */
299             numerical = true;
300          }
301          
302          if ((long)choices->GetCount() != num) { /* new choice has begun */
303             delete choices;
304             choices = new wxArrayString();
305             choices->Add(wxT(""), num); /* fill until this number */
306             numerical = true;
307          }
308          
309          choices->Add(str.Mid(i+2).RemoveLast());
310       }
311       else if (!choices) { /* Introduction, no list received yet */
312          introStr << questionStr;
313          questionStr = wxString(str);
314       }
315       else { /* List receveived, get the question now */
316          introStr << questionStr;
317          questionStr = wxString(str);
318       }
319    }
320    else {
321       finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
322       if (prompt = ((status == CS_PROMPT) && (questionStr != wxT("$ ")))) { // && (str.Find(": ") == str.Length())
323          if (introStr.Last() == '\n') {
324             introStr.RemoveLast();
325          }
326          if ((introStr != wxT("")) && (questionStr == wxT(""))) {
327             questionStr = introStr;
328             introStr = wxT("");
329          }
330          
331          if ((!choices) && (questionStr.Find(wxT("(yes/mod/no)")) > -1)) {
332             choices = new wxArrayString();
333             choices->Add(wxT("yes"));
334             choices->Add(wxT("mod"));
335             choices->Add(wxT("no"));
336             numerical = false;
337          }
338          
339          return true;
340       }
341       else { /* ended or (dis)connected */
342          if (choices) {
343             delete choices;
344             choices = NULL;
345             numerical = false;
346          }
347          questionStr = wxT("");
348          introStr = wxT("");
349       }
350    }
351    return false;
352 }
353
354 /* Returns true if the last signal received was an prompt signal, 
355  * indicating that the answer must be sent */
356 bool wxbPromptParser::hasFinished() {
357    return finished;
358 }
359
360 /* Returns true if the last message received is a prompt message */
361 bool wxbPromptParser::isPrompt() {
362    return prompt;
363 }
364
365 /* Returns multiple choice question's introduction */
366 wxString wxbPromptParser::getIntroString() {
367    return introStr;
368 }
369
370 /* Returns question string */
371 wxString wxbPromptParser::getQuestionString() {
372    return questionStr;
373 }
374
375 /* Returns a wxArrayString containing the indexed choices we have
376  * to answer the question, or NULL if this question is not a multiple
377  * choice one. */
378 wxArrayString* wxbPromptParser::getChoices() {
379    return choices;
380 }
381
382 /* Returns true if the expected answer to the choice list is a number,
383  * false if it is a string (for example yes/mod/no). */
384 bool wxbPromptParser::isNumericalChoice() {
385    return numerical;
386 }