FShGetLine.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 $Header$
00004 
00005 */
00006 
00007 #include <ctype.h>
00008 
00009 #include "Error.h"
00010 #include "FSh.h"
00011 #include "Core.h"
00012 #include "NamedObject.h"
00013 #include "Set.h"
00014 
00015 #include "FShGetLine.h"
00016 
00017 // Public methods.
00018 
00019 FShGetLine::FShGetLine(FSh *shell) : GetLine()
00020 {
00021   int res;
00022 
00023   _forth = FORTH();
00024 
00025   if (!(_shell = shell)) {
00026     failure(ERROR(MSG_NULL_POINTER));
00027     return;
00028   }
00029 
00030   if (!(_connection = shell->_connection)) {
00031     failure(ERROR(MSG_NULL_POINTER));
00032     return;
00033   }
00034 
00035   if (FAILED(res = _connection->writeStr(_forth->output()))) {
00036     failure(ERROR_BACKTRACE(res));
00037     return;
00038   }
00039 
00040   if (FAILED(res = _connection->writeStr(_forth->welcome()))) {
00041     failure(ERROR_BACKTRACE(res));
00042     return;
00043   }
00044   if (FAILED(res = setPrompt(CSTRING(_forth->prompt())))) {
00045     failure(ERROR_BACKTRACE(res));
00046     return;
00047   }
00048 }
00049 
00050 FShGetLine::~FShGetLine()
00051 {
00052 }
00053 
00054 // Protected methods.
00055 
00056 int FShGetLine::onTab(char *buf, const int, int *cursorLoc, int *i)
00057 {
00058   if (*cursorLoc == 0 || strlen(buf) == 0)
00059     return OK;
00060 
00061   String matchedWords;
00062   unsigned int matchedWordsNum = 0;
00063   bool quotation = false;
00064   String completedPart;
00065   StringSet words(_forth->words());
00066   int res;
00067 
00068   words += NamedObject::names();
00069 
00070   int j;
00071   unsigned int wordsPerLine, len;
00072   char *wordPart = buf;
00073 
00074   j = *cursorLoc - 1;
00075   while (j >= 0) {
00076     if (buf[j] == ' ' || buf[j] == '\t' || buf[j] == '"') {
00077       if (buf[j] == '"')
00078         quotation = true;
00079       wordPart = buf + j + 1;
00080       break;
00081     }
00082     --j;
00083   }
00084   if ((len = strlen(wordPart)) == 0)
00085     return OK;
00086 
00087   StringSet::const_iterator k = words.begin();
00088   StringSet::const_iterator e = words.end();
00089 
00090   wordsPerLine = 0;
00091   while (k != e) {
00092     if (strncasecmp(wordPart, CSTRING(*k), len) == 0) {
00093       if (wordsPerLine > 0)
00094         matchedWords += '\t';
00095       matchedWords += *k;
00096       completedPart.intersection(*k, true);
00097       ++matchedWordsNum;
00098       if (++wordsPerLine >= LIMIT_FORTH_WORDS_PER_LINE) {
00099         wordsPerLine = 0;
00100         matchedWords.append(String::eol());
00101       }
00102     }
00103     ++k;
00104   }
00105 
00106   if (matchedWordsNum == 0) {
00107     int actuallyWritten;
00108 
00109     if (FAILED(res = _connection->write(&FSH_GETLINE_BEEP, sizeof(FSH_GETLINE_BEEP), actuallyWritten)))
00110       return ERROR_BACKTRACE(res);
00111 
00112     return OK;
00113   }
00114 
00115   if (matchedWordsNum == 1) {
00116     if (!quotation)
00117       matchedWords += ' ';
00118     strncpy(wordPart, CSTRING(matchedWords), GL_LIMIT_BUFFER_SIZE - 1);
00119     *i = wordPart - buf;
00120     *cursorLoc += matchedWords.length();
00121   } else {
00122       if (FAILED(res = _connection->writeStr(String::eol() + matchedWords + (iscntrl(matchedWords[matchedWords.length() - 1]) ? "" : String::eol()) + prompt() + buf)))
00123         return ERROR_BACKTRACE(res);
00124       if (!completedPart.empty()) {
00125         strncpy(wordPart, CSTRING(completedPart), GL_LIMIT_BUFFER_SIZE - 1);
00126         *i = wordPart - buf;
00127         *cursorLoc += completedPart.length();
00128       }
00129     }
00130 
00131   return OK;
00132 }
00133 
00134 int FShGetLine::onOutput(const char *buf)
00135 {
00136   int res;
00137 
00138   if (strlen(buf) == 0)
00139     if (FAILED(res = CORE()->kill(_shell)))
00140       return ERROR_BACKTRACE(res);
00141 
00142   if (FAILED(res = _forth->eval(buf)))
00143     ERROR_BACKTRACE(res);
00144 
00145   if (FAILED(res = setPrompt(CSTRING(_forth->prompt()))))
00146     return ERROR_BACKTRACE(res);
00147 
00148   String out(_forth->output());
00149   if (!out.empty())
00150     if (FAILED(res = _connection->writeStr(String::eol() + out)))
00151       return ERROR_BACKTRACE(res);
00152 
00153   return OK;
00154 }
00155 
00156 int FShGetLine::onPutc(const char c)
00157 {
00158   int actuallyWritten;
00159   int res;
00160 
00161   if (FAILED(res = _connection->write(&c, sizeof(char), actuallyWritten)))
00162     return ERROR_BACKTRACE(res);
00163   if (c == '\n') {
00164     char ch = '\r'; // RAW mode needs '\r', does not hurt.
00165     if (FAILED(res = _connection->write(&ch, sizeof(char), actuallyWritten)))
00166       return ERROR_BACKTRACE(res);
00167   }
00168 
00169   return OK;
00170 }
00171 
00172 int FShGetLine::onPuts(const char *buf)
00173 {
00174   int actuallyWritten;
00175   int res;
00176 
00177   if (buf)
00178     if (FAILED(res = _connection->write(buf, strlen(buf), actuallyWritten)))
00179       return ERROR_BACKTRACE(res);
00180 
00181   return OK;
00182 }
00183 
00184 // Caclulates length of colored text. Pay attention to non printable characters,
00185 // so according to ANSI terminal definitions all sequences between
00186 // ESC and 'm' treat as non-printable.
00187 unsigned int FShGetLine::onStrlen(const char *str)
00188 {
00189   return String::colorLength(str);
00190 }

Generated on Thu Sep 6 20:11:25 2007 for Pylon Application Platform by  doxygen 1.5.1