/*\r
* AcessOS Shell Version 3\r
*/\r
+#define USE_READLINE 1\r
#include <acess/sys.h>\r
#include <stdlib.h>\r
#include <stdio.h>\r
#include <string.h>\r
#include "header.h"\r
\r
+#if USE_READLINE\r
+# include "readline.h"\r
+#endif\r
+\r
#define _stdin 0\r
#define _stdout 1\r
#define _stderr 2\r
void CallCommand(char **Args);\r
void Command_Logout(int argc, char **argv);\r
void Command_Clear(int argc, char **argv);\r
-void Command_Colour(int argc, char **argv);\r
+void Command_Help(int argc, char **argv);\r
void Command_Cd(int argc, char **argv);\r
void Command_Dir(int argc, char **argv);\r
\r
// ==== CONSTANT GLOBALS ====\r
-char *cCOLOUR_NAMES[8] = {"black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"};\r
struct {\r
char *name;\r
void (*fcn)(int argc, char **argv);\r
} cBUILTINS[] = {\r
{"exit", Command_Logout}, {"logout", Command_Logout},\r
- {"colour", Command_Colour}, {"clear", Command_Clear},\r
+ {"help", Command_Help}, {"clear", Command_Clear},\r
{"cd", Command_Cd}, {"dir", Command_Dir}\r
};\r
static char *cDEFAULT_PATH[] = {"/Acess/Bin"};\r
int main(int argc, char *argv[], char *envp[])\r
{\r
char *sCommandStr;\r
- char *saArgs[32];\r
+ char *saArgs[32] = {0};\r
int length = 0;\r
int i;\r
int iArgCount = 0;\r
+ #if !USE_READLINE\r
int bCached = 1;\r
+ #else\r
+ tReadline *readline_state = Readline_Init(1);\r
+ #endif\r
\r
gasEnvironment = envp;\r
\r
{\r
// Free last command & arguments\r
if(saArgs[0]) free(saArgs);\r
+ #if !USE_READLINE\r
if(!bCached) free(sCommandStr);\r
bCached = 0;\r
+ #endif\r
+ \r
write(_stdout, strlen(gsCurrentDirectory), gsCurrentDirectory);\r
- write(_stdout, 3, "$ ");\r
+ write(_stdout, 2, "$ ");\r
\r
// Read Command line\r
+ #if USE_READLINE\r
+ sCommandStr = Readline( readline_state );\r
+ printf("\n");\r
+ length = strlen(sCommandStr);\r
+ #else\r
sCommandStr = ReadCommandLine( &length );\r
\r
if(!sCommandStr) {\r
gasCommandHistory[ giLastCommand ] = sCommandStr;\r
bCached = 1;\r
}\r
+ #endif\r
\r
// Parse Command Line into arguments\r
Parse_Args(sCommandStr, saArgs);\r
\r
// Shall we?\r
CallCommand( &saArgs[1] );\r
+ \r
+ #if USE_READLINE\r
+ free( sCommandStr );\r
+ #endif\r
}\r
}\r
\r
char *ret;\r
int len, pos, space = 1023;\r
char ch;\r
+ #if 0\r
+ int scrollbackPos = giLastCommand;\r
+ #endif\r
\r
// Preset Variables\r
ret = malloc( space+1 );\r
// Read In Command Line\r
do {\r
read(_stdin, 1, &ch); // Read Character from stdin (read is a blocking call)\r
- // Ignore control characters\r
- if(ch == '\x1B') {\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 '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
- case 'D': if(pos) pos--; break;\r
- case 'C': if(pos<len) pos++; break;\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
- continue;\r
- }\r
+ break;\r
+ \r
// Backspace\r
- if(ch == '\b') {\r
- if(len <= 0) continue; // Protect against underflows\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 --; pos--;\r
- } else {\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
- write(_stdout, 1, &ch);\r
- continue;\r
- }\r
- // Expand Buffer\r
- if(len > space) {\r
- space += 256;\r
- ret = realloc(ret, space+1);\r
- if(!ret) return NULL;\r
- }\r
+ break;\r
+ \r
+ // Tab\r
+ case '\t':\r
+ //TODO: Implement Tab-Completion\r
+ //Currently just ignore tabs\r
+ break;\r
\r
- write(_stdout, 1, &ch);\r
- ret[pos++] = ch;\r
- len ++;\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
- // Remove newline\r
- pos --;\r
- ret[pos] = '\0';\r
+ // Cap String\r
+ ret[len] = '\0';\r
+ printf("\n");\r
\r
// Return length\r
if(Length) *Length = len;\r
}\r
\r
/**\r
- * \fn void Command_Clear(int argc, char **argv)\r
- * \brief Clear the screen\r
+ * \fn void Command_Colour(int argc, char **argv)\r
+ * \brief Displays the help screen\r
*/\r
-void Command_Clear(int argc, char **argv)\r
+void Command_Help(int argc, char **argv)\r
{\r
- write(_stdout, 4, "\x1B[2J"); //Clear Screen\r
+ Print("Acess 2 Command Line Interface\n");\r
+ Print(" By John Hodge (thePowersGang / [TPG])\n");\r
+ Print("\n");\r
+ Print("Builtin Commands:\n");\r
+ Print(" logout: Return to the login prompt\n");\r
+ Print(" exit: Same\n");\r
+ Print(" help: Display this message\n");\r
+ Print(" clear: Clear the screen\n");\r
+ Print(" cd: Change the current directory\n");\r
+ Print(" dir: Print the contents of the current directory\n");\r
+ //Print("\n");\r
+ return;\r
}\r
\r
/**\r
- * \fn void Command_Colour(int argc, char **argv)\r
- * \brief Set the colour of the shell prompt\r
- * \note Conflicts with coloured `dir` display\r
+ * \fn void Command_Clear(int argc, char **argv)\r
+ * \brief Clear the screen\r
*/\r
-void Command_Colour(int argc, char **argv)\r
+void Command_Clear(int argc, char **argv)\r
{\r
- int fg, bg;\r
- char clrStr[6] = "\x1B[37m";\r
- \r
- // Verify Arg Count\r
- if(argc < 2)\r
- {\r
- goto usage;\r
- }\r
- \r
- // Check Colour\r
- for(fg=0;fg<8;fg++)\r
- if(strcmp(cCOLOUR_NAMES[fg], argv[1]) == 0)\r
- break;\r
-\r
- // Foreground a valid colour\r
- if(fg == 8) {\r
- Print("Unknown Colour '");Print(argv[1]);Print("'\n");\r
- goto usage;\r
- }\r
- // Set Foreground\r
- clrStr[3] = '0' + fg;\r
- write(_stdout, 6, clrStr);\r
- \r
- // Need to Set Background?\r
- if(argc > 2)\r
- {\r
- for(bg=0;bg<8;bg++)\r
- if(strcmp(cCOLOUR_NAMES[bg], argv[2]) == 0)\r
- break;\r
- \r
- // Valid colour\r
- if(bg == 8)\r
- {\r
- Print("Unknown Colour '");Print(argv[2]);Print("'\n");\r
- goto usage;\r
- }\r
- \r
- clrStr[2] = '4';\r
- clrStr[3] = '0' + bg;\r
- write(_stdout, 6, clrStr);\r
- }\r
- // Return\r
- return;\r
-\r
- // Function Usage (Requested via a Goto (I know it's ugly))\r
-usage:\r
- Print("Usage: colour <foreground> [<background>]\n");\r
- Print("Valid Colours are ");\r
- for(fg=0;fg<8;fg++)\r
- {\r
- Print(cCOLOUR_NAMES[fg]);\r
- write(_stdout, 3, ", ");\r
- }\r
- write(_stdout, 4, "\b\b\n");\r
- return;\r
+ write(_stdout, 4, "\x1B[2J"); //Clear Screen\r
}\r
\r
/**\r
// Check if file opened\r
if(dp == -1)\r
{\r
- //printf("Unable to open directory `%s', File cannot be found\n", tmpPath);\r
- write(_stdout, 27, "Unable to open directory `");\r
- write(_stdout, strlen(tmpPath)+1, tmpPath);\r
- write(_stdout, 25, "', File cannot be found\n");\r
+ printf("Unable to open directory `%s', File cannot be found\n", tmpPath);\r
return;\r
}\r
// Get File Stats\r