From 83eba1d3db42a048a848ae1839dcfc13f09cf22e Mon Sep 17 00:00:00 2001 From: scottmk Date: Sat, 6 Jun 2009 12:40:00 +0000 Subject: [PATCH] 1. If an input line ends in a backslash, remove the backslash and append the following line as a continuation. 2. Disable the readline library's special treatment of horizontal tabs, which by default trigger file name completion (which is not useful for srfsh). 3. In calls to strtok(): accept horizontal tabs as delimiters, since they are no longer suppressed by readline(). git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1716 9efc2488-bf62-4759-914b-345cdb29e865 --- src/srfsh/srfsh.c | 87 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 10 deletions(-) diff --git a/src/srfsh/srfsh.c b/src/srfsh/srfsh.c index 7a44546..3f84f9b 100644 --- a/src/srfsh/srfsh.c +++ b/src/srfsh/srfsh.c @@ -64,6 +64,7 @@ static int print_help( void ); //static void sig_child_handler( int s ); //static void sig_int_handler( int s ); +static char* get_request( void ); static int load_history( void ); static int handle_math( char* words[] ); static int do_math( int count, int style ); @@ -114,13 +115,17 @@ int main( int argc, char* argv[] ) { /* --------------------------------------------- */ load_history(); - client = osrfSystemGetTransportClient(); + // Disable special treatment for tabs by readline + // (by default they invoke command completion, which + // is not useful for srfsh) + rl_bind_key( '\t', rl_insert ); + /* main process loop */ int newline_needed = 1; /* used as boolean */ char* request; - while((request=readline(prompt))) { + while( (request = get_request()) ) { // Find first non-whitespace character @@ -128,11 +133,6 @@ int main( int argc, char* argv[] ) { while( isspace( (unsigned char) *cmd ) ) ++cmd; - // ignore comments and empty lines - - if( '\0' == *cmd || '#' == *cmd ) - continue; - // 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 @@ -187,6 +187,74 @@ int main( int argc, char* argv[] ) { return 0; } +// Get a logical line from one or more calls to readline(), +// skipping blank lines and comments. Stitch continuation +// lines together as needed. Caller is responsible for +// freeing the string returned. +// If EOF appears before a logical line is completed, +// return NULL. +static char* get_request( void ) { + char* line; + char* p; + + // Get the first physical line of the logical line + while( 1 ) { + line = readline( prompt ); + if( ! line ) + return NULL; // end of file + + // Skip leading white space + for( p = line; isspace( *p ); ++p ) + ; + + if( '\\' == *p && '\0' == p[1] ) { + // Just a trailing backslash; skip to next line + free( line ); + continue; + } else if( '\0' == p[0] || '#' == *p ) { + free( line ); + continue; // blank line or comment; skip it + } else + break; // Not blank, not comment; take it + } + + char* end = line + strlen( line ) - 1; + if( *end != '\\' ) + return line; // No continuation line; we're done + + // Remove the trailing backslash and collect + // the continuation line(s) into a growing_buffer + *end = '\0'; + + growing_buffer* logical_line = buffer_init( 256 ); + buffer_add( logical_line, p ); + free( line ); + + // Append any continuation lines + int finished = 0; // boolean + while( !finished ) { + line = readline( "> " ); + if( line ) { + + // Check for another continuation + end = line + strlen( line ) - 1; + if( '\\' == *end ) + *end = '\0'; + else + finished = 1; + + buffer_add( logical_line, line ); + free( line ); + } else { + fprintf( stderr, "Expected continuation line; found end of file\n" ); + buffer_free( logical_line ); + return NULL; + } + } + + return buffer_release( logical_line ); +} + static int load_history( void ) { char* home = getenv("HOME"); @@ -204,7 +272,6 @@ static int load_history( void ) { static int parse_error( char* words[] ) { - if( ! words ) return 0; @@ -235,7 +302,7 @@ static int parse_request( char* request ) { char* req = request; - char* cur_tok = strtok( req, " " ); + char* cur_tok = strtok( req, " \t" ); if( cur_tok == NULL ) { @@ -249,7 +316,7 @@ static int parse_request( char* request ) { while(cur_tok != NULL) { if( i < COMMAND_BUFSIZE - 1 ) { words[i++] = cur_tok; - cur_tok = strtok( NULL, " " ); + cur_tok = strtok( NULL, " \t" ); } else { fprintf( stderr, "Too many tokens in command\n" ); free( original_request ); -- 2.43.2