Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed-rtos VodafoneUSBModem mbed
Console.cpp
00001 #include "Console.h" 00002 //#define DEBUG 00003 00004 Console::Console(Serial *terminal, int lineLength, int numLines, bool characterBased) 00005 : _terminal(terminal), _lineLength(lineLength), _numLines(numLines), _characterBased(characterBased) { 00006 00007 _terminal->printf("Console ready!\r\n"); 00008 00009 // set the buffer timeout 00010 _bufferWaitTimeout_ms = BUFFER_WAIT_TIMEOUT_MS; 00011 00012 // allocate space for current line 00013 _lineBuffer = (char*)malloc((_lineLength+1)*sizeof(char)); 00014 00015 // character based consoles need a history 00016 if(_characterBased) { 00017 _lines = (char**)malloc(_numLines*sizeof(char*)); 00018 for(int i=0; i<_numLines; i++) { 00019 _lines[i] = (char*)malloc((_lineLength+1)*sizeof(char)); 00020 } 00021 00022 // blank out current line with NULLs 00023 for(int i=0; i<=_lineLength; i++) 00024 _lineBuffer[i] = 0x00; 00025 } 00026 00027 // set line position, number of used lines, and line buffer pointer to 0 00028 _linePos = 0; 00029 _prevLinePos = 0; 00030 _usedLines = 0; 00031 _currentLine = 0; 00032 } 00033 00034 // destructor 00035 Console::~Console() { 00036 free(_lineBuffer); 00037 } 00038 00039 // store the current lineBuffer in the history 00040 void Console::storeBuffer() { 00041 // only do so if history specified 00042 if(_numLines==0) 00043 return; 00044 00045 // imagine the command history as a FILO buffer 00046 // here we rightshift the command history 00047 if(_usedLines==_numLines-1) { 00048 char* p = _lines[0]; 00049 for(int i=0; i<_numLines-1; i++) { 00050 _lines[i] = _lines[i+1]; 00051 } 00052 _lines[_numLines-1] = p; 00053 } 00054 00055 // and insert the current line in the newest position 00056 strncpy(_lines[_usedLines],_lineBuffer,_lineLength+1); 00057 00058 // this just deals with the filling up stage 00059 if(_usedLines<_numLines-1) { 00060 _usedLines++; 00061 if(_currentLine<_usedLines) 00062 _currentLine = _usedLines; 00063 } else { 00064 _currentLine = _usedLines+1; 00065 } 00066 } 00067 00068 // clear the current-line buffer 00069 void Console::clearBuffer() { 00070 _linePos=0; 00071 for(int i=0; i<=_lineLength; i++) 00072 _lineBuffer[i] = 0x00; 00073 } 00074 00075 // load the next buffer in the line history (activated by DOWN key) 00076 void Console::loadNextBuffer() { 00077 if(_currentLine<_usedLines) { 00078 _currentLine++; 00079 } else { 00080 _linePos=0; 00081 for(int i=0; i<=_lineLength; i++) 00082 _lineBuffer[i] = 0x00; 00083 return; 00084 } 00085 strncpy(_lineBuffer,_lines[_currentLine],_lineLength+1); 00086 _prevLinePos = _linePos; 00087 _linePos=0; 00088 while(_lineBuffer[_linePos]!=0x00) 00089 _linePos++; 00090 } 00091 00092 // load the previous buffer in the line history (activated by UP key) 00093 void Console::loadPreviousBuffer() { 00094 if(_currentLine>0) { 00095 _currentLine--; 00096 } 00097 strncpy(_lineBuffer,_lines[_currentLine],_lineLength+1); 00098 _prevLinePos = _linePos; 00099 _linePos=0; 00100 while(_lineBuffer[_linePos]!=0x00) 00101 _linePos++; 00102 } 00103 00104 // process a command entered (received by CRLF) 00105 void Console::processCommand() { 00106 _terminal->printf("Command: \"%s\"\r\n",_lineBuffer); 00107 } 00108 00109 // wait on the console for input, returns false on timeout 00110 // this is useful for processing escape chars 00111 bool Console::waitForInput() { 00112 Timer timer; 00113 timer.start(); 00114 while(!_terminal->readable()&&timer.read_ms()<_bufferWaitTimeout_ms); 00115 return _terminal->readable(); 00116 } 00117 00118 // print the entire command history 00119 void Console::printHistory() { 00120 for(int i=0; i<_numLines; i++) 00121 printBuffer(i); 00122 } 00123 00124 // print the command at index in the history 00125 void Console::printBuffer(int index) { 00126 if(index==_currentLine) 00127 _terminal->printf("> "); 00128 else 00129 _terminal->printf(" "); 00130 _terminal->printf("%d) \"%s\"\r\n",index,_lines[index]); 00131 } 00132 00133 00134 void Console::reprintBuffer() { 00135 _terminal->putc('\r'); 00136 for(int i=0; i<_lineLength; i++) {; 00137 _terminal->putc(' '); 00138 } 00139 00140 _terminal->putc('\r'); 00141 if(_linePos>0) { 00142 _terminal->printf("%s",_lineBuffer); 00143 _terminal->putc('\r'); 00144 for(int i=0; i<_linePos; i++) {; 00145 _terminal->putc(0x1b); 00146 _terminal->putc('['); 00147 _terminal->putc('C'); 00148 } 00149 } 00150 } 00151 00152 // print the current-line buffer including debugging stuff 00153 void Console::printLineBuffer() { 00154 printHistory(); 00155 _terminal->printf("C) \"%s\"\r\n",_lineBuffer); 00156 _terminal->printf(" \""); 00157 for(int i=0; i<_linePos; i++) { 00158 _terminal->printf(" "); 00159 } 00160 _terminal->printf("^"); 00161 for(int i=_linePos+1; i<_lineLength; i++) { 00162 _terminal->printf(" "); 00163 } 00164 _terminal->printf("\"\r\n"); 00165 for(int i=0; i<=_lineLength; i++) { 00166 _terminal->printf("%x ",_lineBuffer[i]); 00167 } 00168 _terminal->printf("\r\n"); 00169 } 00170 00171 void Console::updateLineBased() { 00172 //_terminal->printf("line based\r\n"); 00173 // save until a line is read and then dump to the modem 00174 while(_terminal->readable()) { 00175 int c = _terminal->getc(); 00176 if(_linePos<_lineLength) { 00177 00178 _lineBuffer[_linePos++] = c; 00179 _terminal->printf("%c",c); 00180 // activate process command when 00181 if(c==0x0a) { 00182 processCommand(); 00183 clearBuffer(); 00184 return; 00185 } 00186 } else { 00187 _terminal->printf("WARNING, max line length exceeded!!!"); 00188 } 00189 00190 } 00191 } 00192 00193 void Console::updateCharacterBased() { 00194 // process console input 00195 while(_terminal->readable()) { 00196 int c = _terminal->getc(); 00197 switch(c) { 00198 // backspace 00199 case 0x08: 00200 if(_linePos>0) { 00201 // case where pointer is at end of line 00202 if(_lineBuffer[_linePos]==0x00) { 00203 _lineBuffer[--_linePos] = 0x00; 00204 } else { 00205 // case where pointer is somewhere in the middle of the line 00206 int copyPointer = --_linePos; 00207 while(_lineBuffer[copyPointer]!=0x00) { 00208 _lineBuffer[copyPointer] = _lineBuffer[copyPointer+1]; 00209 copyPointer++; 00210 } 00211 } 00212 00213 reprintBuffer(); 00214 } 00215 break; 00216 00217 // escape sequence 0x1b 0x5b 00218 case 0x1b: 00219 // check that escape sequence exists 00220 if(waitForInput()&&_terminal->getc()==0x5b) { 00221 00222 // process escape characters 00223 if(waitForInput()) { 00224 c = _terminal->getc(); 00225 switch(c) { 00226 // up 00227 case 0x41: 00228 loadPreviousBuffer(); 00229 reprintBuffer(); 00230 break; 00231 00232 // down 00233 case 0x42: 00234 loadNextBuffer(); 00235 reprintBuffer(); 00236 break; 00237 00238 // left 00239 case 0x44: 00240 if(_linePos>0) { 00241 _linePos--; 00242 _terminal->putc('\b'); 00243 } 00244 break; 00245 00246 // right 00247 case 0x43: 00248 // only move right within a string upto its end 00249 if(_lineBuffer[_linePos]!=0x00) { 00250 _linePos++; 00251 _terminal->putc(0x1b); 00252 _terminal->putc('['); 00253 _terminal->putc('C'); 00254 } 00255 break; 00256 } 00257 } 00258 } 00259 break; 00260 00261 // carriage return 00262 case 0x0d: 00263 storeBuffer(); 00264 processCommand(); 00265 clearBuffer(); 00266 break; 00267 00268 default: 00269 if(_linePos<_lineLength) { 00270 // INS mode 00271 if(false) { 00272 _lineBuffer[_linePos++] = c; 00273 _terminal->printf("%c",c); 00274 } else { 00275 if(_lineBuffer[_linePos]==0x00) { 00276 _lineBuffer[_linePos++] = c; 00277 } else { 00278 // move everything to the right 00279 // so long as string end isn't at end of buffer 00280 int strEnd = _linePos; 00281 while(_lineBuffer[++strEnd]!=0x00); 00282 if(strEnd!=_lineLength) { 00283 int copyPointer = _lineLength; 00284 while(--copyPointer!=_linePos) { 00285 _lineBuffer[copyPointer] = _lineBuffer[copyPointer-1]; 00286 } 00287 00288 // insert character 00289 _lineBuffer[_linePos++] = c; 00290 } 00291 } 00292 reprintBuffer(); 00293 } 00294 00295 } 00296 00297 break; 00298 } 00299 00300 #ifdef DEBUG 00301 printLineBuffer(); 00302 #endif 00303 } 00304 } 00305 00306 // process the console 00307 void Console::update() { 00308 if(_characterBased) { 00309 updateCharacterBased(); 00310 } else { 00311 updateLineBased(); 00312 } 00313 }
Generated on Sun Jul 31 2022 23:17:05 by
1.7.2