- // Read In Command Line\r
- do {\r
- read(_stdin, 1, &ch); // Read Character from stdin (read is a blocking call)\r
- \r
- if(ch == '\n') break;\r
- \r
- switch(ch)\r
- {\r
- // Control characters\r
- case '\x1B':\r
- read(_stdin, 1, &ch); // Read control character\r
- switch(ch)\r
- {\r
- //case 'D': if(pos) pos--; break;\r
- //case 'C': if(pos<len) pos++; break;\r
- case '[':\r
- read(_stdin, 1, &ch); // Read control character\r
- switch(ch)\r
- {\r
- #if 0\r
- case 'A': // Up\r
- {\r
- int oldLen = len;\r
- if( scrollbackPos > 0 ) break;\r
- \r
- free(ret);\r
- ret = strdup( gasCommandHistory[--scrollbackPos] );\r
- \r
- len = strlen(ret);\r
- while(pos--) write(_stdout, 3, "\x1B[D");\r
- write(_stdout, len, ret); pos = len;\r
- while(pos++ < oldLen) write(_stdout, 1, " ");\r
- }\r
- break;\r
- case 'B': // Down\r
- {\r
- int oldLen = len;\r
- if( scrollbackPos < giLastCommand-1 ) break;\r
- \r
- free(ret);\r
- ret = strdup( gasCommandHistory[++scrollbackPos] );\r
- \r
- len = strlen(ret);\r
- while(pos--) write(_stdout, 3, "\x1B[D");\r
- write(_stdout, len, ret); pos = len;\r
- while(pos++ < oldLen) write(_stdout, 1, " ");\r
- }\r
- break;\r
- #endif\r
- case 'D': // Left\r
- if(pos == 0) break;\r
- pos --;\r
- write(_stdout, 3, "\x1B[D");\r
- break;\r
- case 'C': // Right\r
- if(pos == len) break;\r
- pos++;\r
- write(_stdout, 3, "\x1B[C");\r
- break;\r
- }\r
- }\r
- break;\r
- \r
- // Backspace\r
- case '\b':\r
- if(len <= 0) break; // Protect against underflows\r
- write(_stdout, 1, &ch);\r
- if(pos == len) { // Simple case of end of string\r
- len --;\r
- pos--;\r
- }\r
- else {\r
- char buf[7] = "\x1B[000D";\r
- buf[2] += ((len-pos+1)/100) % 10;\r
- buf[3] += ((len-pos+1)/10) % 10;\r
- buf[4] += (len-pos+1) % 10;\r
- write(_stdout, len-pos, &ret[pos]); // Move Text\r
- ch = ' '; write(_stdout, 1, &ch); ch = '\b'; // Clear deleted character\r
- write(_stdout, 7, buf); // Update Cursor\r
- // Alter Buffer\r
- memmove(&ret[pos-1], &ret[pos], len-pos);\r
- pos --;\r
- len --;\r
- }\r
- break;\r
- \r
- // Tab\r
- case '\t':\r
- //TODO: Implement Tab-Completion\r
- //Currently just ignore tabs\r
- break;\r
- \r
- default: \r
- // Expand Buffer\r
- if(len+1 > space) {\r
- space += 256;\r
- ret = realloc(ret, space+1);\r
- if(!ret) return NULL;\r
- }\r
- \r
- // Editing inside the buffer\r
- if(pos != len) {\r
- char buf[7] = "\x1B[000D";\r
- buf[2] += ((len-pos)/100) % 10;\r
- buf[3] += ((len-pos)/10) % 10;\r
- buf[4] += (len-pos) % 10;\r
- write(_stdout, 1, &ch); // Print new character\r
- write(_stdout, len-pos, &ret[pos]); // Move Text\r
- write(_stdout, 7, buf); // Update Cursor\r
- memmove( &ret[pos+1], &ret[pos], len-pos );\r
- }\r
- else {\r
- write(_stdout, 1, &ch);\r
- }\r
- ret[pos++] = ch;\r
- len ++;\r
- break;\r
- }\r
- } while(ch != '\n');\r
- \r
- // Cap String\r
- ret[len] = '\0';\r
- printf("\n");\r
- \r
- // Return length\r
- if(Length) *Length = len;\r
- \r
- return ret;\r