+24-04-2003 :
+ - wxbMainFrame : the user is now prompted when an
+ unexpected "question" is asked).
+ - wxbRestorePanel : configure is allowed to change fileset
+ - wxbRestorePanel : using dot commands (.clients, .filesets)
+ - console_thread : implemented prompt and heartbeat messages
+
+23-04-2003 :
+ - general : Don't concatenate lines in csprint, but in wxbDataParser
+ (necessary for dot commands)
+
22-04-2003 :
- wxbRestorePanel : improved restore appearance
- wxbRestorePanel : configure is allowed to change client
wxbRestorePanel : Add buttons to mark/unmark directories/files.
-wxbRestorePanel : Add a button to force the refreshing of the whole tree
+wxbRestorePanel : Add a button to force to refresh the whole tree
wxbRestorePanel : Add a timeout when waiting for commands results
-wxbRestorePanel : Check more carefully which job we just have run.
+wxbMainFrame : Automatically scroll to the last lines of console control.
-wxbRestorePanel : Check if commands run successfully (cd, mark, mods...).
+wxbRestorePanel : Check if commands ran successfully (cd, mark, mods...).
GTK : Improve look
-general : Don't concatenate lines in csprint, but in wxbDataTokenizer
- (necessary for dot commands)
-
-general : use dot commands
+wxbRestorePanel : Use ".default job=RestoreFiles" to get defaults parameters
+ when changing a restore parameter fails.
-wxbRestorePanel : Allow configure to change fileset (need dot)
+console_thread : Allow the user to choose his config file.
-general : Allow the user to be prompted when an unexpected "question"
- is asked ("prompt" data message).
+wxbRestorePanel : Implement BNET_BREAK to break current command
-console_thread : Allow the user to choose his config file.
+general : Implement reconnecting
+
+general : Allow the user to quit however the state is (kill thread if necessary)
+
+wxbDataParser : Add a boolean in the constructor to avoid storing data is
+ will not be used.
wxblistctrl/wxbtreectrl : Find why events are not forwarded correctly
to parent' parent, and correct bad actual implementation.
(remove wxbTreeListPanel)
-
-general : make a good documentation with snapshots
+
+general : find out why I had to modify string.cpp and string.h
+ + In include/wx/string.h, replace line 195 by
+ #if defined(__VISUALC__) // && defined(_MT) && !defined(_DLL)
+ + In src/common/string.cpp, replace line 167 by
+ #if defined(__VISUALC__) // && defined(_MT) && !defined(_DLL)
mingw : correct findlib stat blocks and block size
(Note : nothing to do with wx-console)
+wxbRestorePanel : Check more carefully which job we just have run
+ (needs director modification).
+
+general : make a good documentation with snapshots
+
BUGS
----
sizer->SetSizeHints( this );
this->SetSize(size);
EnableConsole(false);
+
+ nlines = 0;
}
/*
if (ct != NULL) {
ct->Delete();
}
+ else {
+ promptparser = new wxbPromptParser();
+ }
ct = new console_thread();
ct->Create();
ct->Run();
}
// CS_DEBUG is often sent by panels,
- // and resend it to them would sometimes cause an infinite loop
+ // and resend it to them would sometimes cause infinite loops
+
+ /* One promptcaught is normal, so we must have two true Print values to be
+ * sure that the prompt has effectively been caught.
+ */
+ int promptcaught = -1;
+
if (status != CS_DEBUG) {
for (unsigned int i = 0; i < parsers.GetCount(); i++) {
- parsers[i]->Print(str, status);
- }
+ promptcaught += parsers[i]->Print(str, status) ? 1 : 0;
+ }
+
+ if ((status == CS_PROMPT) && (promptcaught < 1) && (promptparser->isPrompt())) {
+ Print("Unexpected question has been received.\n", CS_DEBUG);
+// Print(wxString("(") << promptparser->getIntroString() << "/-/" << promptparser->getQuestionString() << ")\n", CS_DEBUG);
+
+ wxString message;
+ if (promptparser->getIntroString() != "") {
+ message << promptparser->getIntroString() << "\n";
+ }
+ message << promptparser->getQuestionString();
+
+ if (promptparser->getChoices()) {
+ wxString *choices = new wxString[promptparser->getChoices()->GetCount()];
+ int *numbers = new int[promptparser->getChoices()->GetCount()];
+ int n = 0;
+
+ for (unsigned int i = 0; i < promptparser->getChoices()->GetCount(); i++) {
+ if ((*promptparser->getChoices())[i] != "") {
+ choices[n] = (*promptparser->getChoices())[i];
+ numbers[n] = i;
+ n++;
+ }
+ }
+
+ int res = ::wxGetSingleChoiceIndex(message,
+ "wx-console: unexpected director's question.", n, choices, this);
+ if (res == -1) {
+ Send("\n");
+ }
+ else {
+ Send(wxString() << numbers[res] << "\n");
+ }
+ }
+ else {
+ Send(::wxGetTextFromUser(message,
+ "wx-console: unexpected director's question.", "", this) + "\n");
+ }
+ }
}
-
+
if (status == CS_END) {
str = "#";
}
- consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK));
+ if (status == CS_DEBUG) {
+ consoleCtrl->SetDefaultStyle(wxTextAttr(wxColour(0, 128, 0)));
+ }
+ else {
+ consoleCtrl->SetDefaultStyle(wxTextAttr(*wxBLACK));
+ }
(*consoleCtrl) << str;
- consoleCtrl->SetInsertionPointEnd();
+ if (status == CS_PROMPT) {
+ (*consoleCtrl) << "<P>";
+ }
+ /*if (status != CS_DEBUG) {
+ (*consoleCtrl) << "@";
+ }*/
+ //consoleCtrl->SetInsertionPointEnd();
+
+/* if ((consoleCtrl->GetNumberOfLines()-1) > nlines) {
+ nlines = consoleCtrl->GetNumberOfLines()-1;
+ }
+
+ if (status == CS_END) {
+ consoleCtrl->ShowPosition(nlines);
+ }*/
}
/*
typeCtrl->SetValue("");
consoleCtrl->SetDefaultStyle(wxTextAttr(*wxRED));
(*consoleCtrl) << str;
+
+/* if ((consoleCtrl->GetNumberOfLines()-1) > nlines) {
+ nlines = consoleCtrl->GetNumberOfLines()-1;
+ }
+
+ consoleCtrl->ShowPosition(nlines);*/
}
/* Enable panels */
wxbMainFrame::GetInstance()->AddPendingEvent(evt);
}
-wxString csBuffer; /* Temporary buffer for receiving data from console thread */
+//wxString csBuffer; /* Temporary buffer for receiving data from console thread */
/*
* Called by console thread, this function forwards data line by line and end
void csprint(char* str, int status)
{
if (str != 0) {
- int len = strlen(str);
- bool allnewline = true;
- for (int i = 0; i < len; i++) {
- if (!(allnewline = (str[i] == '\n')))
- break;
- }
-
- if (allnewline) {
- firePrintEvent(csBuffer << "\n", CS_DATA);
- csBuffer = "";
- for (int i = 1; i < len; i++) {
- firePrintEvent("\n", status);
- }
- }
- else {
- wxStringTokenizer tkz(str, "\n",
- wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL);
-
- while ( tkz.HasMoreTokens() ) {
- csBuffer << tkz.GetNextToken();
- if (csBuffer.Length() != 0) {
- if ((csBuffer.GetChar(csBuffer.Length()-1) == '\n') ||
- (csBuffer.GetChar(csBuffer.Length()-1) == '\r')) {
- firePrintEvent(csBuffer, status);
- csBuffer = "";
- }
- }
- }
- }
-
- if (csBuffer == "$ ") { // Restore console
- firePrintEvent(csBuffer, status);
- csBuffer = "";
- }
+ firePrintEvent(wxString(str), status);
}
-
- if (status != CS_DATA) {
- if (csBuffer.Length() != 0) {
- firePrintEvent(csBuffer, CS_DATA);
- }
- csBuffer = "";
+ else {
firePrintEvent("", status);
}
}
console_thread* ct; /* thread interacting with the director */
+ wxbPromptParser* promptparser; /* prompt parser catching uncatched questions */
+
static wxbMainFrame *frame; /* this */
+
+ int nlines; /* number of lines in the console */
// any class wishing to process wxWindows events must use this macro
DECLARE_EVENT_TABLE()
ConfigReplace = 9,
ConfigWhen = 10,
ConfigPriority = 11,
- ConfigClient = 12
+ ConfigClient = 12,
+ ConfigFileset = 13
};
BEGIN_EVENT_TABLE(wxbRestorePanel, wxPanel)
EVT_TEXT(ConfigPriority, wxbRestorePanel::OnConfigUpdated)
EVT_CHOICE(ConfigReplace, wxbRestorePanel::OnConfigUpdated)
EVT_CHOICE(ConfigClient, wxbRestorePanel::OnConfigUpdated)
+ EVT_CHOICE(ConfigFileset, wxbRestorePanel::OnConfigUpdated)
EVT_BUTTON(ConfigOk, wxbRestorePanel::OnConfigOk)
EVT_BUTTON(ConfigApply, wxbRestorePanel::OnConfigApply)
cfgWhere = new wxTextCtrl(restorePanel, ConfigWhere, "", wxDefaultPosition, wxDefaultSize);
wxString erlist[] = {"always", "if newer", "if older", "never"};
cfgReplace = new wxChoice(restorePanel, ConfigReplace, wxDefaultPosition, wxDefaultSize, 4, erlist);
- cfgFileset = new wxStaticText(restorePanel, -1, " ", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+ cfgFileset = new wxChoice(restorePanel, ConfigFileset, wxDefaultPosition, wxDefaultSize, 0, elist);
cfgClient = new wxChoice(restorePanel, ConfigClient, wxDefaultPosition, wxDefaultSize, 0, elist);
cfgStorage = new wxStaticText(restorePanel, -1, " ", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
cfgWhen = new wxTextCtrl(restorePanel, ConfigWhen, "0000-00-00 00:00:00", wxDefaultPosition, wxDefaultSize);
cfgSizer->Add(new wxStaticText(restorePanel, -1, "Replace: ", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT), 1, wxEXPAND | wxALIGN_CENTER_HORIZONTAL);
cfgSizer->Add(cfgReplace, 1, wxEXPAND);
cfgSizer->Add(new wxStaticText(restorePanel, -1, "Fileset: ", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT), 1, wxEXPAND | wxALIGN_CENTER_HORIZONTAL);
- cfgSizer->Add(cfgFileset, 1, wxEXPAND | wxADJUST_MINSIZE);
+ cfgSizer->Add(cfgFileset, 1, wxEXPAND);
cfgSizer->Add(new wxStaticText(restorePanel, -1, "Client: ", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT), 1, wxEXPAND | wxALIGN_CENTER_HORIZONTAL);
cfgSizer->Add(cfgClient, 1, wxEXPAND);
cfgSizer->Add(new wxStaticText(restorePanel, -1, "Storage: ", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT), 1, wxEXPAND | wxALIGN_CENTER_HORIZONTAL);
/* The main button has been clicked */
void wxbRestorePanel::CmdStart() {
if (status == activable) {
- wxbTableParser* tableparser = CreateAndWaitForParser("list clients\n");
+ wxbDataTokenizer* dt = WaitForEnd(".clients\n", true, false);
+ wxString str;
clientChoice->Clear();
- for (unsigned int i = 0; i < tableparser->size(); i++) {
- long* j = new long;
- (*tableparser)[i][0].ToLong(j);
- clientChoice->Append((*tableparser)[i][1], (void*)j);
- cfgClient->Append((*tableparser)[i][1]);
+ cfgClient->Clear();
+ for (unsigned int i = 0; i < dt->GetCount(); i++) {
+ str = (*dt)[i];
+ str.RemoveLast();
+ clientChoice->Append(str);
+ cfgClient->Append(str);
}
- delete tableparser;
+ delete dt;
+
+ dt = WaitForEnd(".filesets\n", true, false);
+
+ cfgFileset->Clear();
+ for (unsigned int i = 0; i < dt->GetCount(); i++) {
+ str = (*dt)[i];
+ str.RemoveLast();
+ cfgFileset->Append(str);
+ }
+
+ delete dt;
SetStatus(entered);
}
wxbMainFrame::GetInstance()->SetStatusText("Please select a client.");
return;
}
- WaitForEnd("restore\n");
- WaitForEnd("6\n");
- WaitForEnd(wxString() << jobChoice->GetStringSelection() << "\n");
- WaitForEnd(wxString() << *((long*)clientChoice->GetClientData(clientChoice->GetSelection())) << "\n");
+ WaitForPrompt("restore\n");
+ WaitForPrompt("6\n");
+ wxbPromptParser *pp = WaitForPrompt(wxString() << jobChoice->GetStringSelection() << "\n", true);
+ int client = pp->getChoices()->Index(clientChoice->GetStringSelection());
+ if (client == wxNOT_FOUND) {
+ wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected client.");
+ return;
+ }
+ delete pp;
+ WaitForEnd(wxString() << client << "\n");
WaitForEnd("unmark *\n");
SetStatus(choosing);
wxTreeItemId root = tree->AddRoot(clientChoice->GetStringSelection(), -1, -1, new wxbTreeItemData("/", clientChoice->GetStringSelection(), 0));
totfilemessages = 0;
wxbDataTokenizer* dt;
-
- /*dt = WaitForEnd("estimate\n", true);
-
- int j, k;
-
- for (unsigned int i = 0; i < dt->GetCount(); i++) {*/
- /* 15847 total files; 1 marked to be restored; 1,034 bytes. */
-/* if ((j = (*dt)[i].Find(" marked to be restored;")) > -1) {
- k = (*dt)[i].Find("; ");
- (*dt)[i].Mid(k+2, j).ToLong(&totfilemessages);
- break;
- }
- }
-
- delete dt;*/
-
+
int j;
- dt = WaitForEnd("done\n", true);
+ dt = new wxbDataTokenizer(true);
+ WaitForPrompt("done\n");
for (unsigned int i = 0; i < dt->GetCount(); i++) {
if ((j = (*dt)[i].Find(" files selected to be restored.")) > -1) {
/* 1: Level (not appropriate)
* 2: Storage (automatic ?)
* 3: Job (no)
- * 4: FileSet (no)
- * 5: Client (no)
+ * 4: FileSet (yes)
+ * 5: Client (yes)
* 6: When (yes : "Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now):")
* 7: Priority (yes : "Enter new Priority: (positive integer)")
* 8: Bootstrap (?)
EnableConfig(false);
wxbDataTokenizer* dt = NULL;
+
while (cfgUpdated > 0) {
wxString def; //String to send if can't use our data
if ((cfgUpdated >> ConfigWhere) & 1) {
- WaitForEnd("mod\n"); /* TODO: check results */
- WaitForEnd("9\n");
- dt = WaitForEnd(cfgWhere->GetValue() + "\n", true);
+ WaitForPrompt("mod\n"); /* TODO: check results */
+ WaitForPrompt("9\n");
+ dt = new wxbDataTokenizer(true);
+ WaitForPrompt(cfgWhere->GetValue() + "\n");
def = "/tmp";
cfgUpdated = cfgUpdated & (~(1 << ConfigWhere));
}
else if ((cfgUpdated >> ConfigReplace) & 1) {
- WaitForEnd("mod\n"); /* TODO: check results */
- WaitForEnd("10\n");
- dt = WaitForEnd(wxString() << (cfgReplace->GetSelection()+1) << "\n", true);
+ WaitForPrompt("mod\n"); /* TODO: check results */
+ WaitForPrompt("10\n");
+ dt = new wxbDataTokenizer(true);
+ WaitForPrompt(wxString() << (cfgReplace->GetSelection()+1) << "\n");
def = "1";
cfgUpdated = cfgUpdated & (~(1 << ConfigReplace));
}
else if ((cfgUpdated >> ConfigWhen) & 1) {
- WaitForEnd("mod\n"); /* TODO: check results */
- WaitForEnd("6\n");
- dt = WaitForEnd(cfgWhen->GetValue() + "\n", true);
+ WaitForPrompt("mod\n"); /* TODO: check results */
+ WaitForPrompt("6\n");
+ dt = new wxbDataTokenizer(true);
+ WaitForPrompt(cfgWhen->GetValue() + "\n");
def = "";
cfgUpdated = cfgUpdated & (~(1 << ConfigWhen));
}
else if ((cfgUpdated >> ConfigPriority) & 1) {
- WaitForEnd("mod\n"); /* TODO: check results */
- WaitForEnd("7\n");
- dt = WaitForEnd(cfgPriority->GetValue() + "\n", true);
+ WaitForPrompt("mod\n"); /* TODO: check results */
+ WaitForPrompt("7\n");
+ dt = new wxbDataTokenizer(true);
+ WaitForPrompt(cfgPriority->GetValue() + "\n");
def = "10";
cfgUpdated = cfgUpdated & (~(1 << ConfigPriority));
}
else if ((cfgUpdated >> ConfigClient) & 1) {
- WaitForEnd("mod\n"); /* TODO: check results */
- dt = WaitForEnd("5\n", true);
- wxString sel = cfgClient->GetStringSelection();
- wxString sint = "1";
- if (sel != "") {
- // "The defined Client resources are:\n 1: velours-fd\n 2: tom-fd\nSelect Client (File daemon) resource (1-2):"
- for (unsigned int i = 0; i < dt->GetCount(); i++) {
- int j;
- if ((j = (*dt)[i].Find(": " + sel + "\n")) > -1) {
- sint = (*dt)[i].Mid(0, j).Trim().Trim(false);
- break;
- }
- }
+ WaitForPrompt("mod\n"); /* TODO: check results */
+ wxbPromptParser *pp = WaitForPrompt("5\n", true);
+ int client = pp->getChoices()->Index(cfgClient->GetStringSelection());
+ if (client == wxNOT_FOUND) {
+ wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected client.");
+ client = 1;
}
- delete dt;
- dt = WaitForEnd(sint + "\n", true);
+ delete pp;
+ dt = new wxbDataTokenizer(true);
+ WaitForPrompt(wxString() << client << "\n");
def = "1";
cfgUpdated = cfgUpdated & (~(1 << ConfigClient));
}
+ else if ((cfgUpdated >> ConfigFileset) & 1) {
+ WaitForPrompt("mod\n"); /* TODO: check results */
+ wxbPromptParser *pp = WaitForPrompt("4\n", true);
+ int fileset = pp->getChoices()->Index(cfgFileset->GetStringSelection());
+ if (fileset == wxNOT_FOUND) {
+ wxbMainFrame::GetInstance()->SetStatusText("Failed to find the selected fileset.");
+ fileset = 1;
+ }
+ delete pp;
+ dt = new wxbDataTokenizer(true);
+ WaitForPrompt(wxString() << fileset << "\n");
+ def = "1";
+ cfgUpdated = cfgUpdated & (~(1 << ConfigFileset));
+ }
else {
cfgUpdated = 0;
break;
void wxbRestorePanel::CmdListJobs() {
if (status == entered) {
jobChoice->Clear();
- WaitForEnd("query\n");
- WaitForEnd("6\n");
+ WaitForPrompt("query\n");
+ WaitForPrompt("6\n");
wxbTableParser* tableparser = CreateAndWaitForParser(clientChoice->GetString(clientChoice->GetSelection()) + "\n");
for (int i = tableparser->size()-1; i > -1; i--) {
return tableParser;
}
+/* Run a command, and waits until prompt result is fully received,
+ * if keepresults is true, returns a valid pointer to a wxbPromptParser
+ * containing the data. */
+wxbPromptParser* wxbRestorePanel::WaitForPrompt(wxString cmd, bool keepresults) {
+ wxbPromptParser* promptParser = new wxbPromptParser();
+
+ wxbMainFrame::GetInstance()->Send(cmd);
+
+ //time_t base = wxDateTime::Now().GetTicks();
+ while (!promptParser->hasFinished()) {
+ //innerThread->Yield();
+ wxTheApp->Yield();
+ //if (base+15 < wxDateTime::Now().GetTicks()) break;
+ }
+
+ if (keepresults) {
+ return promptParser;
+ }
+ else {
+ delete promptParser;
+ return NULL;
+ }
+}
+
/* Run a command, and waits until result is fully received. */
-wxbDataTokenizer* wxbRestorePanel::WaitForEnd(wxString cmd, bool keepresults) {
- wxbDataTokenizer* datatokenizer = new wxbDataTokenizer();
+wxbDataTokenizer* wxbRestorePanel::WaitForEnd(wxString cmd, bool keepresults, bool linebyline) {
+ wxbDataTokenizer* datatokenizer = new wxbDataTokenizer(linebyline);
wxbMainFrame::GetInstance()->Send(cmd);
else cfgReplace->SetSelection(0);
if ((k = (*dt)[++i].Find("FileSet:")) != 0) return false;
- cfgFileset->SetLabel((*dt)[i].Mid(10).Trim(false).RemoveLast());
+ str = (*dt)[i].Mid(10).Trim(false).RemoveLast();
+ for (k = 0; k < cfgFileset->GetCount(); k++) {
+ if (str == cfgFileset->GetString(k)) {
+ cfgFileset->SetSelection(k);
+ break;
+ }
+ }
+ if (k == cfgFileset->GetCount()) { // Should never happen
+ cfgFileset->Append(str);
+ cfgFileset->SetSelection(k+1);
+ }
+
if ((k = (*dt)[++i].Find("Client:")) != 0) return false;
str = (*dt)[i].Mid(10).Trim(false).RemoveLast();
for (k = 0; k < cfgClient->GetCount(); k++) {
cfgWhen->Enable(enable);
cfgPriority->Enable(enable);
cfgClient->Enable(enable);
+ cfgFileset->Enable(enable);
}
/*----------------------------------------------------------------------------
}
working = true;
clientChoice->Enable(false);
+ jobChoice->Enable(false);
CmdListJobs();
clientChoice->Enable(true);
+ jobChoice->Enable(true);
jobChoice->Refresh();
working = false;
}
/* Run a command, and waits until result is fully received,
* if keepresults is true, returns a valid pointer to a wxbDataTokenizer
* containing the data. */
- wxbDataTokenizer* WaitForEnd(wxString cmd, bool keepresults = false);
+ wxbDataTokenizer* WaitForEnd(wxString cmd, bool keepresults = false, bool linebyline = true);
+
+ /* Run a command, and waits until prompt result is fully received,
+ * if keepresults is true, returns a valid pointer to a wxbPromptParser
+ * containing the data. */
+ wxbPromptParser* WaitForPrompt(wxString cmd, bool keepresults = false);
/* Run a dir command, and waits until result is fully received. */
void UpdateTreeItem(wxTreeItemId item, bool updatelist);
wxStaticText* cfgBootstrap;
wxTextCtrl* cfgWhere;
wxChoice* cfgReplace;
- wxStaticText* cfgFileset;
+ wxChoice* cfgFileset;
wxChoice* cfgClient;
wxStaticText* cfgStorage;
wxTextCtrl* cfgWhen;
/*
* wxbTableParser constructor
*/
-wxbTableParser::wxbTableParser() : wxbTable(5), wxbDataParser() {
+wxbTableParser::wxbTableParser() : wxbTable(5), wxbDataParser(true) {
separatorNum = 0;
tableHeader = wxbTableRow(5);
}
}
/*
- * Receives director information, forwarded by the wxbPanel which
- * uses this parser.
+ * Receives data to analyse.
*/
-void wxbTableParser::Print(wxString str, int status) {
+bool wxbTableParser::Analyse(wxString str, int status) {
if ((status == CS_END) && (separatorNum > 0)) {
separatorNum = 3;
}
- if (separatorNum == 3) return;
+ if (separatorNum == 3) return false;
if (str.Length() > 4) {
if ((str.GetChar(0) == '+') && (str.GetChar(str.Length()-2) == '+') && (str.GetChar(str.Length()-1) == '\n')) {
separatorNum++;
- return;
+ return false;
}
if ((str.GetChar(0) == '|') && (str.GetChar(str.Length()-2) == '|') && (str.GetChar(str.Length()-1) == '\n')) {
}
}
}
+ return false;
}
/*
virtual ~wxbTableParser();
/*
- * Receives director information, forwarded by the wxbPanel which
- * uses this parser.
+ * Receives data to analyse.
*/
- virtual void Print(wxString str, int status);
+ virtual bool Analyse(wxString str, int status);
/*
* Return true table parsing has finished.
#include "csprint.h"
/* Creates a new wxbDataParser, and register it in wxbMainFrame */
-wxbDataParser::wxbDataParser() {
+wxbDataParser::wxbDataParser(bool lineanalysis) {
wxbMainFrame::GetInstance()->Register(this);
+ this->lineanalysis = lineanalysis;
+// buffer = "";
}
/* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
wxbMainFrame::GetInstance()->Unregister(this);
}
+/*
+ * Receives director information, forwarded by wxbMainFrame, and sends it
+ * line by line to the virtual function Analyse.
+ */
+bool wxbDataParser::Print(wxString str, int status) {
+ bool ret = false;
+ if (lineanalysis) {
+ bool allnewline = true;
+ for (unsigned int i = 0; i < str.Length(); i++) {
+ if (!(allnewline = (str.GetChar(i) == '\n')))
+ break;
+ }
+
+ if (allnewline) {
+ ret = Analyse(buffer << "\n", CS_DATA);
+ buffer = "";
+ for (unsigned int i = 1; i < str.Length(); i++) {
+ ret = Analyse("\n", status);
+ }
+ }
+ else {
+ wxStringTokenizer tkz(str, "\n",
+ wxTOKEN_RET_DELIMS | wxTOKEN_RET_EMPTY | wxTOKEN_RET_EMPTY_ALL);
+
+ while ( tkz.HasMoreTokens() ) {
+ buffer << tkz.GetNextToken();
+ if (buffer.Length() != 0) {
+ if ((buffer.GetChar(buffer.Length()-1) == '\n') ||
+ (buffer.GetChar(buffer.Length()-1) == '\r')) {
+ ret = Analyse(buffer, status);
+ buffer = "";
+ }
+ }
+ }
+ }
+
+ if (buffer == "$ ") { // Restore console
+ ret = Analyse(buffer, status);
+ buffer = "";
+ }
+
+ if (status != CS_DATA) {
+ if (buffer.Length() != 0) {
+ ret = Analyse(buffer, CS_DATA);
+ }
+ buffer = "";
+ ret = Analyse("", status);
+ }
+ }
+ else {
+ ret = Analyse(wxString(str), status);
+ }
+ return ret;
+}
+
/* Creates a new wxbDataTokenizer */
-wxbDataTokenizer::wxbDataTokenizer(): wxbDataParser(), wxArrayString() {
+wxbDataTokenizer::wxbDataTokenizer(bool linebyline): wxbDataParser(linebyline), wxArrayString() {
finished = false;
}
/*
* Receives director information, forwarded by wxbMainFrame.
*/
-void wxbDataTokenizer::Print(wxString str, int status) {
- finished = ((status == CS_END) || (status == CS_DISCONNECTED));
+bool wxbDataTokenizer::Analyse(wxString str, int status) {
+ finished = ((status == CS_END) || (status == CS_PROMPT) || (status == CS_DISCONNECTED));
if (str != "") {
Add(str);
- //wxbMainFrame::GetInstance()->Print("D", CS_DEBUG);
}
- //wxbMainFrame::GetInstance()->Print(finished ? "F" : "!F", CS_DEBUG);
+ return false;
}
/* Returns true if the last signal received was an end signal,
bool wxbDataTokenizer::hasFinished() {
return finished;
}
+
+/* Creates a new wxbDataTokenizer */
+wxbPromptParser::wxbPromptParser(): wxbDataParser(false) {
+ finished = false;
+ prompt = false;
+ introStr = "";
+ choices = NULL;
+ questionStr = "";
+}
+
+/* Destroy a wxbDataTokenizer */
+wxbPromptParser::~wxbPromptParser() {
+ if (choices) {
+ delete choices;
+ }
+}
+
+/*
+ * Receives director information, forwarded by wxbMainFrame.
+ */
+bool wxbPromptParser::Analyse(wxString str, int status) {
+ if (status == CS_DATA) {
+ if (finished || prompt) { /* New question */
+ finished = false;
+ prompt = false;
+ if (choices) {
+ delete choices;
+ choices = NULL;
+ }
+ questionStr = "";
+ introStr = "";
+ }
+ int i;
+ long num;
+
+ if (((i = str.Find(": ")) > 0) && (str.Mid(0, i).Trim(false).ToLong(&num))) { /* List element */
+ if (!choices) {
+ choices = new wxArrayString();
+ choices->Add(""); /* index 0 is never used by multiple choice questions */
+ }
+
+ if (choices->GetCount() != num) { /* new choice has begun */
+ delete choices;
+ choices = new wxArrayString(num);
+ choices->Add("", num); /* fill until this number */
+ }
+
+ choices->Add(str.Mid(i+2).RemoveLast());
+ }
+ else if (!choices) { /* Introduction, no list received yet */
+ introStr << questionStr;
+ questionStr = wxString(str);
+ }
+ else { /* List receveived, get the question now */
+ introStr << questionStr;
+ questionStr = wxString(str);
+ }
+ }
+ else {
+ finished = ((status == CS_PROMPT) || (status == CS_END) || (status == CS_DISCONNECTED));
+ if (prompt = ((status == CS_PROMPT) && (questionStr != "$ "))) { // && (str.Find(": ") == str.Length())
+ if ((introStr != "") && (questionStr == "")) {
+ questionStr = introStr;
+ introStr = "";
+ }
+ if (introStr.Last() == '\n') {
+ introStr.RemoveLast();
+ }
+ return true;
+ }
+ else { /* ended or (dis)connected */
+ if (choices) {
+ delete choices;
+ choices = NULL;
+ }
+ questionStr = "";
+ introStr = "";
+ }
+ }
+ return false;
+}
+
+/* Returns true if the last signal received was an prompt signal,
+ * indicating that the answer must be sent */
+bool wxbPromptParser::hasFinished() {
+ return finished;
+}
+
+/* Returns true if the last message received is a prompt message */
+bool wxbPromptParser::isPrompt() {
+ return prompt;
+}
+
+/* Returns multiple choice question's introduction */
+wxString wxbPromptParser::getIntroString() {
+ return introStr;
+}
+
+/* Returns question string */
+wxString wxbPromptParser::getQuestionString() {
+ return questionStr;
+}
+
+/* Return a wxArrayString containing the indexed choices we have
+ * to answer the question, or NULL if this question is not a multiple
+ * choice one. */
+wxArrayString* wxbPromptParser::getChoices() {
+ return choices;
+}
class wxbDataParser
{
public:
- /* Creates a new wxbDataParser, and register it in wxbMainFrame */
- wxbDataParser();
+ /* Creates a new wxbDataParser, and register it in wxbMainFrame
+ * lineanalysis : indicate if date is to be analysed line by line (true)
+ * or packet by packet (false).
+ */
+ wxbDataParser(bool lineanalysis);
/* Destroy a wxbDataParser, and unregister it in wxbMainFrame */
virtual ~wxbDataParser();
/*
- * Receives director information, forwarded by wxbMainFrame.
+ * Receives director information, forwarded by wxbMainFrame, and sends it
+ * line by line to the virtual function Analyse.
+ *
+ * Returns true if status == CS_PROMPT and the message has been parsed
+ * correctly.
+ */
+ bool Print(wxString str, int status);
+
+ /*
+ * Receives data to analyse.
*/
- virtual void Print(wxString str, int status) = 0;
+ virtual bool Analyse(wxString str, int status) = 0;
+ private:
+ bool lineanalysis;
+ wxString buffer;
};
/*
{
public:
/* Creates a new wxbDataTokenizer */
- wxbDataTokenizer();
+ wxbDataTokenizer(bool linebyline);
/* Destroy a wxbDataTokenizer */
virtual ~wxbDataTokenizer();
/*
- * Receives director information, forwarded by wxbMainFrame.
+ * Receives data to analyse.
*/
- virtual void Print(wxString str, int status);
+ virtual bool Analyse(wxString str, int status);
/* Returns true if the last signal received was an end signal,
* indicating that no more data is available */
private:
bool finished;
- wxString buffer;
+};
+
+/*
+ * Receives director information, and check if the last messages are questions.
+ */
+class wxbPromptParser: public wxbDataParser
+{
+ public:
+ /* Creates a new wxbDataTokenizer */
+ wxbPromptParser();
+
+ /* Destroy a wxbDataTokenizer */
+ virtual ~wxbPromptParser();
+
+ /*
+ * Receives data to analyse.
+ */
+ virtual bool Analyse(wxString str, int status);
+
+ /* Returns true if the last signal received was an prompt signal,
+ * or an end signal */
+ bool hasFinished();
+
+ /* Returns true if the last message received is a prompt message */
+ bool isPrompt();
+
+ /* Returns multiple choice question's introduction */
+ wxString getIntroString();
+
+ /* Returns question string */
+ wxString getQuestionString();
+
+ /* Return a wxArrayString containing the indexed choices we have
+ * to answer the question, or NULL if this question is not a multiple
+ * choice one. */
+ wxArrayString* getChoices();
+
+
+
+ private:
+ bool finished;
+ bool prompt;
+ wxString introStr;
+ wxArrayString* choices;
+ wxString questionStr;
};
#endif // WXBPANEL_H