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