Patch from Scott McKellar to clean up srfsh's user interface:
authormiker <miker@9efc2488-bf62-4759-914b-345cdb29e865>
Sun, 15 Jul 2007 02:18:41 +0000 (02:18 +0000)
committermiker <miker@9efc2488-bf62-4759-914b-345cdb29e865>
Sun, 15 Jul 2007 02:18:41 +0000 (02:18 +0000)
1. srfsh exits the main loop in two circumstances.  The first is when
it sees the "quit" or "exit" command.  The second is when it sees
end-of-file, either because it reads the end of a script or because
the user enters the associated keystrokes (typically Control-D).

In the case of end-of-file, srfsh exits without issuing another
newline.  As a result, the next shell prompt shows up concatenated
to the srfsh prompt.  This result is harmless but annoying.

I tweaked the code to detect this situation and issue an extra
newline, so that the next shell prompt show up on a line by itself.

2. I strip off leading whitespace before processing the input
command.

As a result, srfsh will now recognize "quit", "exit", or a leading
exclamation point, even when preceded by whitespace.  Other commands
are not affected because strtok() already strips off leading
blanks.  Tab characters don't matter because readline() removes them.

3. I also strip off trailing whitespace.  This measure affects only
the "quit" and "exit" commands.

4. I ignore input lines whose first non-whitespace character is an
octothorpe ('#', also known as hash, pound, or tic-tac-toe).  In
other words, scripts can now have comments.

git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1035 9efc2488-bf62-4759-914b-345cdb29e865

src/srfsh/srfsh.c

index 29b8bbf..37a767b 100644 (file)
@@ -2,6 +2,7 @@
 #include <opensrf/osrf_message.h>
 #include <opensrf/osrf_app_session.h>
 #include <time.h>
+#include <ctype.h>
 #include <sys/timeb.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -118,16 +119,46 @@ int main( int argc, char* argv[] ) {
        client = osrf_system_get_transport_client();
 
        /* main process loop */
+       int newline_needed = 1;  /* used as boolean */
        char* request;
        while((request=readline(prompt))) {
 
-               if( !strcasecmp(request, "exit") || !strcasecmp(request,"quit")) 
-                       break; 
+               // Find first non-whitespace character
+               
+               char * cmd = request;
+               while( isspace( (unsigned char) *cmd ) )
+                       ++cmd;
+
+               // ignore comments and empty lines
+
+               if( '\0' == *cmd || '#' == *cmd )
+                       continue;
 
-               char* req_copy = strdup(request);
+               // Remove trailing whitespace.  We know at this point that
+               // there is at least one non-whitespace character somewhere,
+               // or we would have already skipped this line.  Hence we
+               // needn't check to make sure that we don't back up past
+               // the beginning.
+
+               {
+                       // The curly braces limit the scope of the end variable
+                       
+                       char * end = cmd + strlen(cmd) - 1;
+                       while( isspace( (unsigned char) *end ) )
+                               --end;
+                       end[1] = '\0';
+               }
+
+               if( !strcasecmp(cmd, "exit") || !strcasecmp(cmd, "quit"))
+               {
+                       newline_needed = 0;
+                       break; 
+               }
+               
+               char* req_copy = strdup(cmd);
 
                parse_request( req_copy ); 
-               if( request && strlen(request) > 1 ) {
+               if( request && *cmd ) {
                        add_history(request);
                }
 
@@ -138,6 +169,15 @@ int main( int argc, char* argv[] ) {
                fflush(stdout);
        }
 
+       if( newline_needed ) {
+               
+               // We left the readline loop after seeing an EOF, not after
+               // seeing "quit" or "exit".  So we issue a newline in order
+               // to avoid leaving a dangling prompt.
+
+               putchar( '\n' );
+       }
+
        if(history_file != NULL )
                write_history(history_file);