Enhance shell.
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 6 Apr 2005 21:13:00 +0000 (21:13 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 6 Apr 2005 21:13:00 +0000 (21:13 +0000)
src/tests/userprog/shell.c

index cfff4e37ea329f5fc1cef3eb0c7b2ca82b77c5c3..d31eb3a9a67c534199f0731165295e0a117b1b7e 100644 (file)
@@ -1,59 +1,27 @@
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 #include <syscall.h>
 
+static void read_line (char line[], size_t);
+static bool backspace (char **pos, char line[]);
+
 int
 main (void)
 {
   printf ("Shell starting...\n");
   for (;;) 
     {
-      char command[80], *cp;
+      char command[80];
 
-      /* Prompt. */
+      /* Read command. */
       printf ("--");
-
-      /* Read and echo command. */
-      cp = command;
-      for (;;)
-        {
-          char c;
-          read (STDIN_FILENO, &c, 1);
-
-          switch (c) 
-            {
-            case '\n':
-              /* Done. */
-              goto got_cmd;
-
-            case '\b':
-              /* Back up cursor, overwrite character, back up again. */
-              printf ("\b \b");
-              break;
-
-            case 27:                    /* Escape. */
-            case ('U' - 'A') + 1:       /* Ctrl+U. */
-              /* Clear entire line. */
-              printf ("\n--");
-              cp = command;
-              break;
-
-            default:
-              /* Add character to line. */
-              *cp++ = c;
-              if (cp >= command + sizeof command - 1)
-                goto got_cmd;
-              break;
-            }
-        }
-    got_cmd:
-      *cp = '\0';
-      putchar ('\n');
+      read_line (command, sizeof command);
       
       /* Execute command. */
       if (!strcmp (command, "exit"))
         break;
-      else if (cp == command
+      else if (command[0] == '\0'
         {
           /* Empty command. */
         }
@@ -70,3 +38,62 @@ main (void)
   printf ("Shell exiting.");
   return 0;
 }
+
+/* Reads a line of input from the user into LINE, which has room
+   for SIZE bytes.  Handles backspace and Ctrl+U in the ways
+   expected by Unix users.  On return, LINE will always be
+   null-terminated and will not end in a new-line character. */
+static void
+read_line (char line[], size_t size) 
+{
+  char *pos = line;
+  for (;;)
+    {
+      char c;
+      read (STDIN_FILENO, &c, 1);
+
+      switch (c) 
+        {
+        case '\n':
+          *pos = '\0';
+          putchar ('\n');
+          return;
+
+        case '\b':
+          backspace (&pos, line);
+          break;
+
+        case ('U' - 'A') + 1:       /* Ctrl+U. */
+          while (backspace (&pos, line))
+            continue;
+          break;
+
+        default:
+          /* Add character to line. */
+          if (pos < line + size - 1) 
+            {
+              putchar (c);
+              *pos++ = c;
+            }
+          break;
+        }
+    }
+}
+
+/* If *POS is past the beginning of LINE, backs up one character
+   position.  Returns true if successful, false if nothing was
+   done. */
+static bool
+backspace (char **pos, char line[]) 
+{
+  if (*pos > line)
+    {
+      /* Back up cursor, overwrite character, back up
+         again. */
+      printf ("\b \b");
+      (*pos)--;
+      return true;
+    }
+  else
+    return false;
+}