diff --git a/env_universal_common.cpp b/env_universal_common.cpp index 66a97fe18..26f986c8a 100644 --- a/env_universal_common.cpp +++ b/env_universal_common.cpp @@ -688,17 +688,17 @@ static int try_send( message_t *msg, { debug( 3, - L"before write of %d chars to fd %d", strlen(msg->body), fd ); + L"before write of %d chars to fd %d", msg->body.size(), fd ); - ssize_t res = write( fd, msg->body, strlen(msg->body) ); + ssize_t res = write( fd, msg->body.c_str(), msg->body.size() ); if( res != -1 ) { - debug( 4, L"Wrote message '%s'", msg->body ); + debug( 4, L"Wrote message '%s'", msg->body.c_str() ); } else { - debug( 4, L"Failed to write message '%s'", msg->body ); + debug( 4, L"Failed to write message '%s'", msg->body.c_str() ); } if( res == -1 ) @@ -722,7 +722,7 @@ static int try_send( message_t *msg, if( !msg->count ) { - free( msg ); + delete msg; } return 1; } @@ -780,17 +780,39 @@ static wcstring full_escape( const wchar_t *in ) return out; } - -message_t *create_message( int type, - const wchar_t *key_in, - const wchar_t *val_in ) +/* Sets the body of a message to the null-terminated list of null terminated const char *. */ +void set_body(message_t *msg, ...) { - message_t *msg=0; + /* Start by counting the length of all the strings */ + size_t body_len = 0; + const char *arg; + va_list arg_list; + va_start(arg_list, msg); + while ((arg = va_arg(arg_list, const char *)) != NULL) + body_len += strlen(arg); + va_end(arg_list); + + /* Reserve that length in the string */ + msg->body.reserve(body_len + 1); //+1 for trailing NULL? Do I need that? + + /* Set the string contents */ + va_start(arg_list, msg); + while ((arg = va_arg(arg_list, const char *)) != NULL) + msg->body.append(arg); + va_end(arg_list); +} + +/* Returns an instance of message_t allocated via new */ +message_t *create_message( int type, + const wchar_t *key_in, + const wchar_t *val_in ) +{ + message_t *msg = new message_t; + msg->count = 0; char *key=0; - size_t sz; - -// debug( 4, L"Crete message of type %d", type ); + + // debug( 4, L"Crete message of type %d", type ); if( key_in ) { @@ -804,8 +826,8 @@ message_t *create_message( int type, if( !key ) { debug( 0, - L"Could not convert %ls to narrow character string", - key_in ); + L"Could not convert %ls to narrow character string", + key_in ); return 0; } } @@ -821,74 +843,42 @@ message_t *create_message( int type, val_in=L""; } - wcstring esc = full_escape( val_in ); + wcstring esc = full_escape( val_in ); char *val = wcs2utf(esc.c_str()); - - sz = strlen(type==SET?SET_MBS:SET_EXPORT_MBS) + strlen(key) + strlen(val) + 4; - msg = (message_t *)malloc( sizeof( message_t ) + sz ); - - if( !msg ) - DIE_MEM(); - - strcpy( msg->body, (type==SET?SET_MBS:SET_EXPORT_MBS) ); - strcat( msg->body, " " ); - strcat( msg->body, key ); - strcat( msg->body, ":" ); - strcat( msg->body, val ); - strcat( msg->body, "\n" ); - + set_body(msg, (type==SET?SET_MBS:SET_EXPORT_MBS), " ", key, ":", val, "\n", NULL); free( val ); break; } - + case ERASE: { - sz = strlen(ERASE_MBS) + strlen(key) + 3; - msg = (message_t *)malloc( sizeof( message_t ) + sz ); - - if( !msg ) - DIE_MEM(); - - strcpy( msg->body, ERASE_MBS " " ); - strcat( msg->body, key ); - strcat( msg->body, "\n" ); + set_body(msg, ERASE_MBS, " ", key, "\n", NULL); break; } - + case BARRIER: { - msg = (message_t *)malloc( sizeof( message_t ) + - strlen( BARRIER_MBS ) +2); - if( !msg ) - DIE_MEM(); - strcpy( msg->body, BARRIER_MBS "\n" ); + set_body(msg, BARRIER_MBS, "\n", NULL); break; } - + case BARRIER_REPLY: { - msg = (message_t *)malloc( sizeof( message_t ) + - strlen( BARRIER_REPLY_MBS ) +2); - if( !msg ) - DIE_MEM(); - strcpy( msg->body, BARRIER_REPLY_MBS "\n" ); + set_body(msg, BARRIER_REPLY_MBS, "\n", NULL); break; } - + default: { debug( 0, L"create_message: Unknown message type" ); } } - + free( key ); - - if( msg ) - msg->count=0; - -// debug( 4, L"Message body is '%s'", msg->body ); - + + // debug( 4, L"Message body is '%s'", msg->body ); + return msg; } diff --git a/env_universal_common.h b/env_universal_common.h index 14ce77d21..11991dcd4 100644 --- a/env_universal_common.h +++ b/env_universal_common.h @@ -3,6 +3,7 @@ #include #include +#include #include "util.h" /** @@ -63,12 +64,13 @@ typedef struct Number of queues that contain this message. Once this reaches zero, the message should be deleted */ int count; + /** Message body. The message must be allocated using enough memory to actually contain the message. */ - char body[1]; -} - message_t; + std::string body; + +} message_t; typedef std::queue message_queue_t; diff --git a/expand.cpp b/expand.cpp index 9a7c77175..34525f003 100644 --- a/expand.cpp +++ b/expand.cpp @@ -1176,10 +1176,10 @@ static int expand_variables_internal( parser_t &parser, wchar_t * const in, std: /** Perform bracket expansion */ -static int expand_brackets(parser_t &parser, const wchar_t *in, int flags, std::vector &out ) +static int expand_brackets(parser_t &parser, const wcstring &instr, int flags, std::vector &out ) { const wchar_t *pos; - int syntax_error=0; + bool syntax_error = false; int bracket_count=0; const wchar_t *bracket_begin=0, *bracket_end=0; @@ -1187,9 +1187,8 @@ static int expand_brackets(parser_t &parser, const wchar_t *in, int flags, std:: const wchar_t *item_begin; size_t len1, len2, tot_len; - - CHECK( in, 0 ); -// CHECK( out, 0 ); + + const wchar_t * const in = instr.c_str(); for( pos=in; (*pos) && !syntax_error; @@ -1215,7 +1214,7 @@ static int expand_brackets(parser_t &parser, const wchar_t *in, int flags, std:: if( bracket_count < 0 ) { - syntax_error = 1; + syntax_error = true; } break; } @@ -1231,7 +1230,7 @@ static int expand_brackets(parser_t &parser, const wchar_t *in, int flags, std:: { if( !(flags & ACCEPT_INCOMPLETE) ) { - syntax_error = 1; + syntax_error = true; } else { @@ -1248,7 +1247,7 @@ static int expand_brackets(parser_t &parser, const wchar_t *in, int flags, std:: mod.push_back(BRACKET_END); } - return expand_brackets( parser, mod.c_str(), 1, out ); + return expand_brackets( parser, mod, 1, out ); } } @@ -1276,17 +1275,16 @@ static int expand_brackets(parser_t &parser, const wchar_t *in, int flags, std:: { if( (*pos == BRACKET_SEP) || (pos==bracket_end) ) { - wchar_t *whole_item; assert(pos >= item_begin); size_t item_len = pos-item_begin; - - whole_item = (wchar_t *)malloc( sizeof(wchar_t)*(tot_len + item_len + 1) ); - wcslcpy( whole_item, in, len1+1 ); - wcslcpy( whole_item+len1, item_begin, item_len+1 ); - wcscpy( whole_item+len1+item_len, bracket_end+1 ); - - expand_brackets( parser, whole_item, flags, out ); - + + wcstring whole_item; + whole_item.reserve(tot_len + item_len + 2); + whole_item.append(in, len1); + whole_item.append(item_begin, item_len); + whole_item.append(bracket_end + 1); + expand_brackets( parser, whole_item, flags, out ); + item_begin = pos+1; if( pos == bracket_end ) break; @@ -1615,7 +1613,7 @@ int expand_string( const wcstring &input, std::vector &output, exp { wcstring next = in->at(i).completion; - if( !expand_brackets( parser, next.c_str(), flags, *out )) + if( !expand_brackets( parser, next, flags, *out )) { return EXPAND_ERROR; } diff --git a/screen.cpp b/screen.cpp index 12389454e..32191cc6f 100644 --- a/screen.cpp +++ b/screen.cpp @@ -870,6 +870,7 @@ void s_write( screen_t *s, wcstring truncated_autosuggestion_line; if (newline_count == 0 && prompt_width + max_line_width >= screen_width && prompt_width + explicit_portion_width < screen_width) { + assert(screen_width - prompt_width >= 1); max_line_width = screen_width - prompt_width - 1; truncated_autosuggestion_line = wcstring(commandline, 0, last_char_that_fits); truncated_autosuggestion_line.push_back(ellipsis_char);