+// 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 );
+}
+