diff --git a/builtin.cpp b/builtin.cpp index 1eaec88e1..4af4f208e 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -116,18 +116,27 @@ bool builtin_data_t::operator<(const builtin_data_t *other) const int builtin_out_redirect; int builtin_err_redirect; -/* - Buffers for storing the output of builtin functions -*/ -string_buffer_t *sb_out=0, *sb_err=0; +/* Buffers for storing the output of builtin functions */ +wcstring stdout_buffer, stderr_buffer; + +const wcstring &get_stdout_buffer() { + ASSERT_IS_MAIN_THREAD(); + return stdout_buffer; +} + +const wcstring &get_stderr_buffer() { + ASSERT_IS_MAIN_THREAD(); + return stderr_buffer; +} + /** Stack containing builtin I/O for recursive builtin calls. */ struct io_stack_elem_t { int in; - string_buffer_t *out; - string_buffer_t *err; + wcstring out; + wcstring err; }; static std::stack io_stack; @@ -167,13 +176,15 @@ static void builtin_wperror( const wchar_t *s) { if( s != 0 ) { - sb_append( sb_err, s, L": ", NULL ); + stderr_buffer.append(s); + stderr_buffer.append(L": "); } char *err = strerror( errno ); wchar_t *werr = str2wcs( err ); if( werr ) { - sb_append( sb_err, werr, L"\n", NULL ); + stderr_buffer.append(werr); + stderr_buffer.push_back(L'\n'); free( werr ); } } @@ -219,15 +230,14 @@ wcstring builtin_help_get( parser_t &parser, const wchar_t *name ) */ -static void builtin_print_help( parser_t &parser, const wchar_t *cmd, string_buffer_t *b ) +static void builtin_print_help( parser_t &parser, const wchar_t *cmd, wcstring &b ) { int is_short = 0; - if( b == sb_err ) + if( &b == &stderr_buffer ) { - sb_append( sb_err, - parser.current_line() ); + stderr_buffer.append(parser.current_line()); } const wcstring h = builtin_help_get( parser, cmd ); @@ -239,7 +249,7 @@ static void builtin_print_help( parser_t &parser, const wchar_t *cmd, string_buf if( str ) { - if( b==sb_err ) + if( &b == &stderr_buffer ) { /* @@ -319,10 +329,10 @@ static void builtin_print_help( parser_t &parser, const wchar_t *cmd, string_buf } } - sb_append( b, str ); + b.append(str); if( is_short ) { - sb_printf( b, _(L"%ls: Type 'help %ls' for related documentation\n\n"), cmd, cmd ); + append_format(b, _(L"%ls: Type 'help %ls' for related documentation\n\n"), cmd, cmd); } free( str ); @@ -334,11 +344,8 @@ static void builtin_print_help( parser_t &parser, const wchar_t *cmd, string_buf */ static void builtin_unknown_option( parser_t &parser, const wchar_t *cmd, const wchar_t *opt ) { - sb_printf( sb_err, - BUILTIN_ERR_UNKNOWN, - cmd, - opt ); - builtin_print_help( parser, cmd, sb_err ); + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, cmd, opt); + builtin_print_help( parser, cmd, stderr_buffer ); } /** @@ -346,11 +353,8 @@ static void builtin_unknown_option( parser_t &parser, const wchar_t *cmd, const */ static void builtin_missing_argument( parser_t &parser, const wchar_t *cmd, const wchar_t *opt ) { - sb_printf( sb_err, - BUILTIN_ERR_MISSING, - cmd, - opt ); - builtin_print_help( parser, cmd, sb_err ); + append_format(stderr_buffer, BUILTIN_ERR_MISSING, cmd, opt); + builtin_print_help( parser, cmd, stderr_buffer ); } /* @@ -400,12 +404,12 @@ static void builtin_bind_list() wcstring tname; if( input_terminfo_get_name(seq, tname) ) { - sb_printf( sb_out, L"bind -k %ls %ls\n", tname.c_str(), ecmd.c_str() ); + append_format(stdout_buffer, L"bind -k %ls %ls\n", tname.c_str(), ecmd.c_str() ); } else { const wcstring eseq = escape_string( seq, 1 ); - sb_printf( sb_out, L"bind %ls %ls\n", eseq.c_str(), ecmd.c_str() ); + append_format(stdout_buffer, L"bind %ls %ls\n", eseq.c_str(), ecmd.c_str() ); } } } @@ -424,7 +428,7 @@ static void builtin_bind_key_names( int all ) { const wcstring &name = names.at(i); - sb_printf( sb_out, L"%ls\n", name.c_str() ); + append_format(stdout_buffer, L"%ls\n", name.c_str() ); } } @@ -439,7 +443,7 @@ static void builtin_bind_function_names() for( size_t i=0; i ev; event_get( &search, &ev ); - sb_append( out, - L"function ", - name.c_str(), - NULL); + out.append(L"function "); + out.append(name); if( desc && wcslen(desc) ) { wchar_t *esc_desc = escape( desc, 1 ); - sb_append( out, L" --description ", esc_desc, NULL ); + out.append(L" --description "); + out.append( esc_desc ); free( esc_desc ); } if( !function_get_shadows( name ) ) { - sb_append( out, L" --no-scope-shadowing", NULL ); + out.append(L" --no-scope-shadowing" ); } for( size_t i=0; iparam1.signal ) ); + append_format( out, L" --on-signal %ls", sig2wcs( next->param1.signal ) ); break; } case EVENT_VARIABLE: { - sb_printf( out, L" --on-variable %ls", next->str_param1.c_str() ); + append_format( out, L" --on-variable %ls", next->str_param1.c_str() ); break; } case EVENT_EXIT: { if( next->param1.pid > 0 ) - sb_printf( out, L" --on-process-exit %d", next->param1.pid ); + append_format( out, L" --on-process-exit %d", next->param1.pid ); else - sb_printf( out, L" --on-job-exit %d", -next->param1.pid ); + append_format( out, L" --on-job-exit %d", -next->param1.pid ); break; } @@ -1134,13 +1135,13 @@ static void functions_def( const wcstring &name, string_buffer_t *out ) { job_t *j = job_get( next->param1.job_id ); if( j ) - sb_printf( out, L" --on-job-exit %d", j->pgid ); + append_format( out, L" --on-job-exit %d", j->pgid ); break; } case EVENT_GENERIC: { - sb_printf( out, L" --on-event %ls", next->str_param1.c_str() ); + append_format( out, L" --on-event %ls", next->str_param1.c_str() ); break; } @@ -1152,15 +1153,15 @@ static void functions_def( const wcstring &name, string_buffer_t *out ) wcstring_list_t named = function_get_named_arguments( name ); if( named.size() > 0 ) { - sb_printf( out, L" --argument" ); + append_format( out, L" --argument" ); for( size_t i=0; i < named.size(); i++ ) { - sb_printf( out, L" %ls", named.at(i).c_str() ); + append_format( out, L" %ls", named.at(i).c_str() ); } } - sb_printf( out, L"\n\t%ls\nend\n", def ); + append_format( out, L"\n\t%ls\nend\n", def ); } @@ -1236,11 +1237,11 @@ static int builtin_functions( parser_t &parser, wchar_t **argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; @@ -1262,7 +1263,7 @@ static int builtin_functions( parser_t &parser, wchar_t **argv ) break; case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return STATUS_BUILTIN_OK; case 'q': @@ -1286,11 +1287,11 @@ static int builtin_functions( parser_t &parser, wchar_t **argv ) */ if( (erase + (!!desc) + list + query + copy) > 1 ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Invalid combination of options\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -1308,22 +1309,22 @@ static int builtin_functions( parser_t &parser, wchar_t **argv ) if( argc-woptind != 1 ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Expected exactly one function name\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } func = argv[woptind]; if( !function_exists( func ) ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Function '%ls' does not exist\n" ), argv[0], func ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -1340,28 +1341,22 @@ static int builtin_functions( parser_t &parser, wchar_t **argv ) std::sort(names.begin(), names.end()); if( is_screen ) { - string_buffer_t buff; - sb_init( &buff ); + wcstring buff; for( i=0; i common_get_width() ) { chars = 0; - sb_append(sb_err, L"\n" ); + stderr_buffer.push_back(L'\n'); } - sb_append( sb_err, - nxt, L" ", NULL ); + stderr_buffer.append(nxt); + stderr_buffer.append(L" "); } - sb_append( sb_err, L"\n" ); + stderr_buffer.push_back(L'\n'); parser.pop_block(); parser.push_block( FAKE ); @@ -1837,16 +1832,16 @@ static int builtin_random( parser_t &parser, wchar_t **argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); break; case '?': @@ -1871,7 +1866,7 @@ static int builtin_random( parser_t &parser, wchar_t **argv ) } lrand48_r( &seed_buffer, &res ); - sb_printf( sb_out, L"%d\n", abs(res%32767) ); + append_format(stdout_buffer, L"%d\n", abs(res%32767) ); break; } @@ -1884,7 +1879,7 @@ static int builtin_random( parser_t &parser, wchar_t **argv ) foo = wcstol( argv[woptind], &end, 10 ); if( errno || *end ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Seed value '%ls' is not a valid number\n" ), argv[0], argv[woptind] ); @@ -1898,11 +1893,11 @@ static int builtin_random( parser_t &parser, wchar_t **argv ) default: { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Expected zero or one argument, got %d\n" ), argv[0], argc-woptind ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } } @@ -1993,11 +1988,11 @@ static int builtin_read( parser_t &parser, wchar_t **argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; @@ -2038,7 +2033,7 @@ static int builtin_read( parser_t &parser, wchar_t **argv ) break; case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return STATUS_BUILTIN_OK; case L'?': @@ -2050,21 +2045,21 @@ static int builtin_read( parser_t &parser, wchar_t **argv ) if( ( place & ENV_UNEXPORT ) && ( place & ENV_EXPORT ) ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_EXPUNEXP, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } if( (place&ENV_LOCAL?1:0) + (place & ENV_GLOBAL?1:0) + (place & ENV_UNIVERSAL?1:0) > 1) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_GLOCAL, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -2078,7 +2073,7 @@ static int builtin_read( parser_t &parser, wchar_t **argv ) if( !wcslen( argv[i] ) ) { - sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] ); + append_format(stderr_buffer, BUILTIN_ERR_VARNAME_ZERO, argv[0] ); return STATUS_BUILTIN_ERROR; } @@ -2086,8 +2081,8 @@ static int builtin_read( parser_t &parser, wchar_t **argv ) { if( (!iswalnum(*src)) && (*src != L'_' ) ) { - sb_printf( sb_err, BUILTIN_ERR_VARCHAR, argv[0], *src ); - builtin_print_help( parser, argv[0], sb_err ); + append_format(stderr_buffer, BUILTIN_ERR_VARCHAR, argv[0], *src ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } } @@ -2327,11 +2322,11 @@ static int builtin_status( parser_t &parser, wchar_t **argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; case 'c': @@ -2359,7 +2354,7 @@ static int builtin_status( parser_t &parser, wchar_t **argv ) break; case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return STATUS_BUILTIN_OK; case 'j': @@ -2371,7 +2366,7 @@ static int builtin_status( parser_t &parser, wchar_t **argv ) job_control_mode = JOB_CONTROL_NONE; else { - sb_printf( sb_err, + append_format(stderr_buffer, L"%ls: Invalid job control mode '%ls'\n", woptarg ); res = 1; @@ -2408,14 +2403,14 @@ static int builtin_status( parser_t &parser, wchar_t **argv ) if( !fn ) fn = _(L"Standard input"); - sb_printf( sb_out, L"%ls\n", fn ); + append_format(stdout_buffer, L"%ls\n", fn ); break; } case CURRENT_LINE_NUMBER: { - sb_printf( sb_out, L"%d\n", parser.get_lineno() ); + append_format(stdout_buffer, L"%d\n", parser.get_lineno() ); break; } @@ -2442,22 +2437,22 @@ static int builtin_status( parser_t &parser, wchar_t **argv ) case STACK_TRACE: { - parser.stack_trace( parser.current_block, sb_out ); + parser.stack_trace( parser.current_block, stdout_buffer ); break; } case NORMAL: { if( is_login ) - sb_printf( sb_out, _( L"This is a login shell\n" ) ); + append_format(stdout_buffer, _( L"This is a login shell\n" ) ); else - sb_printf( sb_out, _( L"This is not a login shell\n" ) ); + append_format(stdout_buffer, _( L"This is not a login shell\n" ) ); - sb_printf( sb_out, _( L"Job control: %ls\n" ), + append_format(stdout_buffer, _( L"Job control: %ls\n" ), job_control_mode==JOB_CONTROL_INTERACTIVE?_( L"Only on interactive jobs" ): (job_control_mode==JOB_CONTROL_NONE ? _( L"Never" ) : _( L"Always" ) ) ); - parser.stack_trace( parser.current_block, sb_out ); + parser.stack_trace( parser.current_block, stdout_buffer ); break; } } @@ -2490,11 +2485,11 @@ static int builtin_exit( parser_t &parser, wchar_t **argv ) ec = wcstol(argv[1],&end,10); if( errno || *end != 0) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Argument '%ls' must be an integer\n" ), argv[0], argv[1] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } break; @@ -2502,11 +2497,11 @@ static int builtin_exit( parser_t &parser, wchar_t **argv ) default: { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -2532,7 +2527,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) dir_in = env_get_string( L"HOME" ); if( dir_in.missing_or_empty() ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Could not find home directory\n" ), argv[0] ); } @@ -2546,21 +2541,21 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) { if( errno == ENOTDIR ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: '%ls' is not a directory\n" ), argv[0], dir_in.c_str() ); } else if( errno == ENOENT ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: The directory '%ls' does not exist\n" ), argv[0], dir_in.c_str() ); } else if( errno == EROTTEN ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: '%ls' is a rotten symlink\n" ), argv[0], dir_in.c_str() ); @@ -2568,7 +2563,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) } else { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Unknown error trying to locate directory '%ls'\n" ), argv[0], dir_in.c_str() ); @@ -2578,9 +2573,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) if( !is_interactive ) { - sb_append( sb_err, - parser.current_line(), - NULL ); + stderr_buffer.append(parser.current_line()); } res = 1; @@ -2593,7 +2586,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) status = wstat( dir, &buffer ); if( !status && S_ISDIR(buffer.st_mode)) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Permission denied: '%ls'\n" ), argv[0], dir ); @@ -2602,7 +2595,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) else { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: '%ls' is not a directory\n" ), argv[0], dir ); @@ -2610,9 +2603,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) if( !is_interactive ) { - sb_append( sb_err, - parser.current_line(), - NULL ); + stderr_buffer.append(parser.current_line()); } res = 1; @@ -2620,7 +2611,7 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) else if( !env_set_pwd() ) { res=1; - sb_printf( sb_err, _( L"%ls: Could not set PWD variable\n" ), argv[0] ); + append_format(stderr_buffer, _( L"%ls: Could not set PWD variable\n" ), argv[0] ); } free(dir); @@ -2636,7 +2627,7 @@ static int builtin_count( parser_t &parser, wchar_t ** argv ) { int argc; argc = builtin_count_args( argv ); - sb_printf( sb_out, L"%d\n", argc-1 ); + append_format(stdout_buffer, L"%d\n", argc-1 ); return !(argc-1); } @@ -2683,16 +2674,16 @@ static int builtin_contains( parser_t &parser, wchar_t ** argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return STATUS_BUILTIN_OK; @@ -2713,7 +2704,7 @@ static int builtin_contains( parser_t &parser, wchar_t ** argv ) needle = argv[woptind]; if (!needle) { - sb_printf( sb_err, _( L"%ls: Key not specified\n" ), argv[0] ); + append_format(stderr_buffer, _( L"%ls: Key not specified\n" ), argv[0] ); } @@ -2758,7 +2749,7 @@ static int builtin_source( parser_t &parser, wchar_t ** argv ) if( wstat(argv[1], &buf) == -1 ) { - sb_printf( sb_err, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] ); + append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] ); builtin_wperror( L"." ); return STATUS_BUILTIN_ERROR; @@ -2766,13 +2757,13 @@ static int builtin_source( parser_t &parser, wchar_t ** argv ) if( !S_ISREG(buf.st_mode) ) { - sb_printf( sb_err, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] ); + append_format(stderr_buffer, _( L"%ls: '%ls' is not a file\n" ), argv[0], argv[1] ); return STATUS_BUILTIN_ERROR; } if( ( fd = wopen( argv[1], O_RDONLY ) ) == -1 ) { - sb_printf( sb_err, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] ); + append_format(stderr_buffer, _(L"%ls: Error encountered while sourcing file '%ls':\n"), argv[0], argv[1] ); builtin_wperror( L"." ); return STATUS_BUILTIN_ERROR; } @@ -2806,7 +2797,7 @@ static int builtin_source( parser_t &parser, wchar_t ** argv ) if( res ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Error while reading file '%ls'\n" ), argv[0], fn_intern == intern_static(L"-") ? L"" : fn_intern ); @@ -2862,10 +2853,10 @@ static int builtin_fg( parser_t &parser, wchar_t **argv ) } if( !j ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: There are no suitable jobs\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); } } else if( argv[2] != 0 ) @@ -2891,19 +2882,19 @@ static int builtin_fg( parser_t &parser, wchar_t **argv ) if( found_job ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Ambiguous job\n" ), argv[0] ); } else { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: '%ls' is not a job\n" ), argv[0], argv[1] ); } - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); j=0; @@ -2917,32 +2908,32 @@ static int builtin_fg( parser_t &parser, wchar_t **argv ) if( *end || errno ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_NOT_NUMBER, argv[0], argv[1] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); } else { j = job_get_from_pid( pid ); if( !j || !job_get_flag( j, JOB_CONSTRUCTED ) || job_is_completed( j )) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: No suitable job: %d\n" ), argv[0], pid ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); j=0; } else if( !job_get_flag( j, JOB_CONTROL) ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Can't put job %d, '%ls' to foreground because it is not under job control\n" ), argv[0], pid, j->command_cstr() ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); j=0; } } @@ -2952,7 +2943,7 @@ static int builtin_fg( parser_t &parser, wchar_t **argv ) { if( builtin_err_redirect ) { - sb_printf( sb_err, + append_format(stderr_buffer, FG_MSG, j->job_id, j->command_cstr() ); @@ -2991,26 +2982,26 @@ static int send_to_bg( parser_t &parser, job_t *j, const wchar_t *name ) { if( j == 0 ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Unknown job '%ls'\n" ), L"bg", name ); - builtin_print_help( parser, L"bg", sb_err ); + builtin_print_help( parser, L"bg", stderr_buffer ); return STATUS_BUILTIN_ERROR; } else if( !job_get_flag( j, JOB_CONTROL ) ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Can't put job %d, '%ls' to background because it is not under job control\n" ), L"bg", j->job_id, j->command_cstr() ); - builtin_print_help( parser, L"bg", sb_err ); + builtin_print_help( parser, L"bg", stderr_buffer ); return STATUS_BUILTIN_ERROR; } else { - sb_printf( sb_err, + append_format(stderr_buffer, _(L"Send job %d '%ls' to background\n"), j->job_id, j->command_cstr() ); @@ -3043,7 +3034,7 @@ static int builtin_bg( parser_t &parser, wchar_t **argv ) if( !j ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: There are no suitable jobs\n" ), argv[0] ); res = 1; @@ -3066,7 +3057,7 @@ static int builtin_bg( parser_t &parser, wchar_t **argv ) pid = (int)wcstol( argv[i], &end, 10 ); if( errno || pid < 0 || *end || !job_get_from_pid( pid ) ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: '%ls' is not a job\n" ), argv[0], argv[i] ); @@ -3100,26 +3091,26 @@ static int builtin_for( parser_t &parser, wchar_t **argv ) if( argc < 3) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_FOR_ERR_COUNT, argv[0] , argc ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); } else if ( wcsvarname(argv[1]) ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_FOR_ERR_NAME, argv[0], argv[1] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); } else if (wcscmp( argv[2], L"in") != 0 ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_FOR_ERR_IN, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); } else { @@ -3176,11 +3167,11 @@ static int builtin_end( parser_t &parser, wchar_t **argv ) { if( !parser.current_block->outer ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Not inside of block\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } else @@ -3300,10 +3291,10 @@ static int builtin_else( parser_t &parser, wchar_t **argv ) parser.current_block->type != IF || parser.current_block->state1() != 1) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Not inside of 'if' block\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } else @@ -3334,12 +3325,12 @@ static int builtin_break_continue( parser_t &parser, wchar_t **argv ) if( argc != 1 ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], argv[1] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -3353,10 +3344,10 @@ static int builtin_break_continue( parser_t &parser, wchar_t **argv ) if( b == 0 ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Not inside of loop\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -3410,20 +3401,20 @@ static int builtin_return( parser_t &parser, wchar_t **argv ) status = wcstol(argv[1],&end,10); if( errno || *end != 0) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Argument '%ls' must be an integer\n" ), argv[0], argv[1] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } break; } default: - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Too many arguments\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -3437,10 +3428,10 @@ static int builtin_return( parser_t &parser, wchar_t **argv ) if( b == 0 ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Not inside of function\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -3468,12 +3459,12 @@ static int builtin_switch( parser_t &parser, wchar_t **argv ) if( argc != 2 ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Expected exactly one argument, got %d\n" ), argv[0], argc-1 ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); res=1; parser.push_block( FAKE ); } @@ -3500,10 +3491,10 @@ static int builtin_case( parser_t &parser, wchar_t **argv ) if( parser.current_block->type != SWITCH ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: 'case' command while not in switch block\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return STATUS_BUILTIN_ERROR; } @@ -3645,7 +3636,7 @@ int builtin_run( parser_t &parser, const wchar_t * const *argv, io_data_t *io ) { if( argv[2] == 0 && (parser.is_help( argv[1], 0 ) ) ) { - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return STATUS_BUILTIN_OK; } } @@ -3693,36 +3684,30 @@ void builtin_push_io( parser_t &parser, int in ) ASSERT_IS_MAIN_THREAD(); if( builtin_stdin != -1 ) { - struct io_stack_elem_t elem = {builtin_stdin, sb_out, sb_err}; + struct io_stack_elem_t elem = {builtin_stdin, stdout_buffer, stderr_buffer}; io_stack.push(elem); } builtin_stdin = in; - sb_out = (string_buffer_t *)malloc(sizeof(string_buffer_t)); - sb_err = (string_buffer_t *)malloc(sizeof(string_buffer_t)); - sb_init( sb_out ); - sb_init( sb_err ); + stdout_buffer.clear(); + stderr_buffer.clear(); } void builtin_pop_io(parser_t &parser) { ASSERT_IS_MAIN_THREAD(); builtin_stdin = 0; - sb_destroy( sb_out ); - sb_destroy( sb_err ); - free( sb_out); - free(sb_err); - if( ! io_stack.empty() ) { struct io_stack_elem_t &elem = io_stack.top(); - sb_err = elem.err; - sb_out = elem.out; + stderr_buffer = elem.err; + stdout_buffer = elem.out; builtin_stdin = elem.in; io_stack.pop(); } else { - sb_out = sb_err = 0; + stdout_buffer.clear(); + stderr_buffer.clear(); builtin_stdin = 0; } } diff --git a/builtin.h b/builtin.h index 2e86c1d0b..29b6fa130 100644 --- a/builtin.h +++ b/builtin.h @@ -92,12 +92,16 @@ enum /** Stringbuffer used to represent standard output */ -extern string_buffer_t *sb_out; +//extern string_buffer_t *sb_out; /** Stringbuffer used to represent standard error */ -extern string_buffer_t *sb_err; +//extern string_buffer_t *sb_err; + +/** Get the string used to represent stdout and stderr */ +const wcstring &get_stdout_buffer(); +const wcstring &get_stderr_buffer(); /** Kludge. Tells builtins if output is to screen diff --git a/builtin_commandline.cpp b/builtin_commandline.cpp index f45c9f290..d470a3913 100644 --- a/builtin_commandline.cpp +++ b/builtin_commandline.cpp @@ -179,8 +179,7 @@ static void write_part( const wchar_t *begin, } } - sb_append( sb_out, - (wchar_t *)out.buff ); + stdout_buffer.append((const wchar_t *)out.buff); free( buff ); tok_destroy( &tok ); @@ -200,8 +199,8 @@ static void write_part( const wchar_t *begin, // debug( 0, L"woot2 %ls -> %ls", buff, esc ); - sb_append( sb_out, esc ); - sb_append( sb_out, L"\n" ); + stdout_buffer.append(esc); + stdout_buffer.append(L"\n"); free( esc ); free( buff ); @@ -255,11 +254,9 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv ) return 1; } - sb_append( sb_err, - argv[0], - L": Can not set commandline in non-interactive mode\n", - NULL ); - builtin_print_help( parser, argv[0], sb_err ); + stderr_buffer.append(argv[0]); + stderr_buffer.append(L": Can not set commandline in non-interactive mode\n"); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } @@ -351,11 +348,11 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format( stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; @@ -418,7 +415,7 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv ) break; case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return 0; case L'?': @@ -436,22 +433,22 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv ) */ if( buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode || search_mode ) { - sb_printf(sb_err, + append_format(stderr_buffer, BUILTIN_ERR_COMBO, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } if( argc == woptind ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_MISSING, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } for( i=woptind; i 1) ) { - sb_append( sb_err, + append_format(stderr_buffer, argv[0], L": Too many arguments\n", NULL ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } if( (buffer_part || tokenize || cut_at_cursor) && (cursor_mode || line_mode || search_mode) ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_COMBO, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } if( (tokenize || cut_at_cursor) && (argc-woptind) ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_COMBO2, argv[0], L"--cut-at-cursor and --tokenize can not be used when setting the commandline" ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } if( append_mode && !(argc-woptind) ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_COMBO2, argv[0], L"insertion mode switches can not be used when not in insertion mode" ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } @@ -552,11 +549,11 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv ) new_pos = wcstol( argv[woptind], &endptr, 10 ); if( *endptr || errno ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_NOT_NUMBER, argv[0], argv[woptind] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); } current_buffer = reader_get_buffer(); @@ -566,7 +563,7 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv ) } else { - sb_printf( sb_out, L"%d\n", reader_get_cursor_pos() ); + append_format(stdout_buffer, L"%d\n", reader_get_cursor_pos() ); return 0; } @@ -576,7 +573,7 @@ static int builtin_commandline( parser_t &parser, wchar_t **argv ) { int pos = reader_get_cursor_pos(); const wchar_t *buff = reader_get_buffer(); - sb_printf( sb_out, L"%d\n", parse_util_lineno( buff, pos ) ); + append_format(stdout_buffer, L"%d\n", parse_util_lineno( buff, pos ) ); return 0; } diff --git a/builtin_complete.cpp b/builtin_complete.cpp index 24175c96a..39b599205 100644 --- a/builtin_complete.cpp +++ b/builtin_complete.cpp @@ -397,11 +397,11 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); res = 1; @@ -434,7 +434,7 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) } else { - sb_printf( sb_err, L"%ls: Invalid token '%ls'\n", argv[0], woptarg ); + append_format(stderr_buffer, L"%ls: Invalid token '%ls'\n", argv[0], woptarg ); res = 1; } break; @@ -481,7 +481,7 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) break; case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return 0; case '?': @@ -499,12 +499,12 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) { if( parser.test( condition, 0, 0, 0 ) ) { - sb_printf( sb_err, + append_format(stderr_buffer, L"%ls: Condition '%ls' contained a syntax error\n", argv[0], condition ); - parser.test( condition, 0, sb_err, argv[0] ); + parser.test( condition, 0, &stderr_buffer, argv[0] ); res = 1; } @@ -517,12 +517,12 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) { if( parser.test_args( comp, 0, 0 ) ) { - sb_printf( sb_err, + append_format(stderr_buffer, L"%ls: Completion '%ls' contained a syntax error\n", argv[0], comp ); - parser.test_args( comp, sb_err, argv[0] ); + parser.test_args( comp, &stderr_buffer, argv[0] ); res = 1; } @@ -567,11 +567,11 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) if( !(next.description).empty() ) { - sb_printf( sb_out, L"%ls%ls\t%ls\n", prepend, next.completion.c_str(), next.description.c_str() ); + append_format(stdout_buffer, L"%ls%ls\t%ls\n", prepend, next.completion.c_str(), next.description.c_str() ); } else { - sb_printf( sb_out, L"%ls%ls\n", prepend, next.completion.c_str() ); + append_format(stdout_buffer, L"%ls%ls\n", prepend, next.completion.c_str() ); } } @@ -583,10 +583,10 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) } else if( woptind != argc ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: Too many arguments\n" ), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); res = 1; } @@ -594,7 +594,7 @@ static int builtin_complete( parser_t &parser, wchar_t **argv ) { /* No arguments specified, meaning we print the definitions of * all specified completions to stdout.*/ - complete_print( sb_out ); + complete_print( stdout_buffer ); } else { diff --git a/builtin_jobs.cpp b/builtin_jobs.cpp index aacae8d22..1aecf51db 100644 --- a/builtin_jobs.cpp +++ b/builtin_jobs.cpp @@ -84,24 +84,22 @@ static void builtin_jobs_print( job_t *j, int mode, int header ) /* Print table header before first job */ - sb_append( sb_out, _( L"Job\tGroup\t" )); + stdout_buffer.append( _( L"Job\tGroup\t" )); #ifdef HAVE__PROC_SELF_STAT - sb_append( sb_out, _( L"CPU\t" ) ); + stdout_buffer.append( _( L"CPU\t" ) ); #endif - sb_append( sb_out, _( L"State\tCommand\n" ) ); + stdout_buffer.append( _( L"State\tCommand\n" ) ); } - sb_printf( sb_out, L"%d\t%d\t", j->job_id, j->pgid ); + append_format(stdout_buffer, L"%d\t%d\t", j->job_id, j->pgid ); #ifdef HAVE__PROC_SELF_STAT - sb_printf( sb_out, L"%d%%\t", cpu_use(j) ); + append_format(stdout_buffer, L"%d%%\t", cpu_use(j) ); #endif - sb_append( sb_out, - job_is_stopped(j)?_(L"stopped"):_(L"running"), - L"\t", - j->command_cstr(), - L"\n", - NULL ); + stdout_buffer.append(job_is_stopped(j)?_(L"stopped"):_(L"running")); + stdout_buffer.append(L"\t"); + stdout_buffer.append(j->command_cstr()); + stdout_buffer.append(L"\t"); break; } @@ -112,9 +110,9 @@ static void builtin_jobs_print( job_t *j, int mode, int header ) /* Print table header before first job */ - sb_append( sb_out, _( L"Group\n" )); + stdout_buffer.append( _( L"Group\n" )); } - sb_printf( sb_out, L"%d\n", j->pgid ); + append_format(stdout_buffer, L"%d\n", j->pgid ); break; } @@ -125,12 +123,12 @@ static void builtin_jobs_print( job_t *j, int mode, int header ) /* Print table header before first job */ - sb_append( sb_out, _( L"Procces\n" )); + stdout_buffer.append( _( L"Procces\n" )); } for( p=j->first_process; p; p=p->next ) { - sb_printf( sb_out, L"%d\n", p->pid ); + append_format(stdout_buffer, L"%d\n", p->pid ); } break; } @@ -142,12 +140,12 @@ static void builtin_jobs_print( job_t *j, int mode, int header ) /* Print table header before first job */ - sb_append( sb_out, _( L"Command\n" )); + stdout_buffer.append( _( L"Command\n" )); } for( p=j->first_process; p; p=p->next ) { - sb_printf( sb_out, L"%ls\n", p->argv0() ); + append_format(stdout_buffer, L"%ls\n", p->argv0() ); } break; } @@ -217,12 +215,12 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; @@ -247,7 +245,7 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv ) } case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return 0; case '?': @@ -300,7 +298,7 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv ) pid=wcstol( argv[i], &end, 10 ); if( errno || *end ) { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: '%ls' is not a job\n" ), argv[0], argv[i] ); @@ -315,7 +313,7 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv ) } else { - sb_printf( sb_err, + append_format(stderr_buffer, _( L"%ls: No suitable job: %d\n" ), argv[0], pid ); @@ -343,7 +341,7 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv ) if( !found ) { - sb_printf( sb_out, + append_format(stdout_buffer, _( L"%ls: There are no jobs\n" ), argv[0] ); } diff --git a/builtin_set.cpp b/builtin_set.cpp index f316ce4a0..87f95dbef 100644 --- a/builtin_set.cpp +++ b/builtin_set.cpp @@ -26,6 +26,8 @@ Functions used for implementing the set builtin. #include "proc.h" #include "parser.h" +/* We know about these buffers */ +extern wcstring stdout_buffer, stderr_buffer; /** Error message for invalid path operations @@ -91,12 +93,7 @@ static int my_env_set( const wchar_t *key, wcstring_list_t &val, int scope ) { const wchar_t *colon; - sb_printf( sb_err, - _(BUILTIN_SET_PATH_ERROR), - L"set", - dir, - key ); - + append_format(stderr_buffer, _(BUILTIN_SET_PATH_ERROR), L"set", dir, key); colon = wcschr( dir, L':' ); if( colon && *(colon+1) ) @@ -113,12 +110,7 @@ static int my_env_set( const wchar_t *key, wcstring_list_t &val, int scope ) if( show_hint ) { - sb_printf( sb_err, - _(BUILTIN_SET_PATH_HINT), - L"set", - key, - key, - wcschr( dir, L':' )+1); + append_format(stderr_buffer, _(BUILTIN_SET_PATH_HINT), L"set", key, key, wcschr( dir, L':' )+1); } if( error ) @@ -156,14 +148,14 @@ static int my_env_set( const wchar_t *key, wcstring_list_t &val, int scope ) { case ENV_PERM: { - sb_printf( sb_err, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key ); + append_format(stderr_buffer, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key); retcode=1; break; } case ENV_INVALID: { - sb_printf( sb_err, _(L"%ls: Unknown error"), L"set" ); + append_format(stderr_buffer, _(L"%ls: Unknown error"), L"set" ); retcode=1; break; } @@ -208,7 +200,7 @@ static int parse_index( std::vector &indexes, if (*src != L'[') { - sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), L"set" ); + append_format(stderr_buffer, _(BUILTIN_SET_ARG_COUNT), L"set" ); return 0; } @@ -216,7 +208,7 @@ static int parse_index( std::vector &indexes, if( (wcsncmp( src_orig, name, len )!=0) || (wcslen(name) != (len)) ) { - sb_printf( sb_err, + append_format(stderr_buffer, _(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"), L"set", name, @@ -244,7 +236,7 @@ static int parse_index( std::vector &indexes, if( end==src || errno ) { - sb_printf(sb_err, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src); + append_format(stderr_buffer, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src); return 0; } @@ -326,7 +318,7 @@ static void print_variables(int include_values, int esc, int scope) const wcstring key = names.at(i); const wcstring e_key = escape_string(key, 0); - sb_append(sb_out, e_key.c_str()); + stdout_buffer.append(e_key); if( include_values ) { @@ -343,17 +335,18 @@ static void print_variables(int include_values, int esc, int scope) wcstring e_value = esc ? expand_escape_variable(value) : value; - sb_append(sb_out, L" ", e_value.c_str(), NULL); + stdout_buffer.append(L" "); + stdout_buffer.append(e_value); if( shorten ) { - sb_append(sb_out, L"\u2026"); + stdout_buffer.append(L"\u2026"); } } } - sb_append(sb_out, L"\n"); + stdout_buffer.append(L"\n"); } } @@ -487,7 +480,7 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) break; case 'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return 0; case '?': @@ -510,11 +503,11 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) if( query && (erase || list || global || local || universal || exportv || unexport ) ) { - sb_printf(sb_err, + append_format(stderr_buffer, BUILTIN_ERR_COMBO, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } @@ -522,11 +515,11 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) /* We can't both list and erase varaibles */ if( erase && list ) { - sb_printf(sb_err, + append_format(stderr_buffer, BUILTIN_ERR_COMBO, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } @@ -535,10 +528,10 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) */ if( local + global + universal > 1 ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_GLOCAL, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } @@ -547,10 +540,10 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) */ if( exportv && unexport ) { - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_EXPUNEXP, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } @@ -596,7 +589,7 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) if( !parse_index( indexes, arg, dest, result.size() ) ) { - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); retcode = 1; break; } @@ -638,11 +631,11 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) if( erase ) { - sb_printf( sb_err, + append_format(stderr_buffer, _(L"%ls: Erase needs a variable name\n%ls\n"), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); retcode = 1; } else @@ -667,15 +660,15 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) if( !wcslen( dest ) ) { free( dest ); - sb_printf( sb_err, BUILTIN_ERR_VARNAME_ZERO, argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + append_format(stderr_buffer, BUILTIN_ERR_VARNAME_ZERO, argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } if( (bad_char = wcsvarname( dest ) ) ) { - sb_printf( sb_err, BUILTIN_ERR_VARCHAR, argv[0], *bad_char ); - builtin_print_help( parser, argv[0], sb_err ); + append_format(stderr_buffer, BUILTIN_ERR_VARCHAR, argv[0], *bad_char ); + builtin_print_help( parser, argv[0], stderr_buffer ); free( dest ); return 1; } @@ -683,8 +676,8 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) if( slice && erase && (scope != ENV_USER) ) { free( dest ); - sb_printf( sb_err, _(L"%ls: Can not specify scope when erasing array slice\n"), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + append_format(stderr_buffer, _(L"%ls: Can not specify scope when erasing array slice\n"), argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } @@ -712,7 +705,7 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) { if( !parse_index( indexes, argv[woptind], dest, result.size() ) ) { - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); retcode = 1; break; } @@ -724,8 +717,8 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) { if( val_count < idx_count ) { - sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + append_format(stderr_buffer, _(BUILTIN_SET_ARG_COUNT), argv[0] ); + builtin_print_help( parser, argv[0], stderr_buffer ); retcode=1; break; } @@ -762,9 +755,9 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) indexes, value ) ) { - sb_printf( sb_err, L"%ls: ", argv[0] ); - sb_printf( sb_err, ARRAY_BOUNDS_ERR ); - sb_append( sb_err, L"\n" ); + append_format(stderr_buffer, L"%ls: ", argv[0] ); + append_format(stderr_buffer, ARRAY_BOUNDS_ERR ); + stderr_buffer.push_back(L'\n'); } my_env_set(dest, result, scope); @@ -792,10 +785,10 @@ static int builtin_set( parser_t &parser, wchar_t **argv ) { if( woptind != argc ) { - sb_printf( sb_err, + append_format(stderr_buffer, _(L"%ls: Values cannot be specfied with erase\n"), argv[0] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); retcode=1; } else diff --git a/builtin_ulimit.cpp b/builtin_ulimit.cpp index 13231ab08..93e37cc54 100644 --- a/builtin_ulimit.cpp +++ b/builtin_ulimit.cpp @@ -144,9 +144,9 @@ static void print( int resource, int hard ) rlim_t l = get( resource, hard ); if( l == RLIM_INFINITY ) - sb_append( sb_out, L"unlimited\n" ); + stdout_buffer.append( L"unlimited\n" ); else - sb_printf( sb_out, L"%d\n", l / get_multiplier( resource ) ); + append_format(stdout_buffer, L"%d\n", l / get_multiplier( resource ) ); } @@ -172,7 +172,7 @@ static void print_all( int hard ) const wchar_t *unit = ((resource_arr[i].resource==RLIMIT_CPU)?L"(seconds, ":(get_multiplier(resource_arr[i].resource)==1?L"(":L"(kB, ")); - sb_printf( sb_out, + append_format(stdout_buffer, L"%-*ls %10ls-%lc) ", w, resource_arr[i].desc, @@ -181,11 +181,11 @@ static void print_all( int hard ) if( l == RLIM_INFINITY ) { - sb_append( sb_out, L"unlimited\n" ); + stdout_buffer.append( L"unlimited\n" ); } else { - sb_printf( sb_out, L"%d\n", l/get_multiplier(resource_arr[i].resource) ); + append_format(stdout_buffer, L"%d\n", l/get_multiplier(resource_arr[i].resource) ); } } @@ -240,7 +240,7 @@ static int set( int resource, int hard, int soft, rlim_t value ) if( setrlimit( resource, &ls ) ) { if( errno == EPERM ) - sb_printf( sb_err, L"ulimit: Permission denied when changing resource of type '%ls'\n", get_desc( resource ) ); + append_format(stderr_buffer, L"ulimit: Permission denied when changing resource of type '%ls'\n", get_desc( resource ) ); else builtin_wperror( L"ulimit" ); return 1; @@ -347,11 +347,11 @@ static int builtin_ulimit( parser_t &parser, wchar_t ** argv ) case 0: if(long_options[opt_index].flag != 0) break; - sb_printf( sb_err, + append_format(stderr_buffer, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; @@ -415,7 +415,7 @@ static int builtin_ulimit( parser_t &parser, wchar_t ** argv ) #endif case L'h': - builtin_print_help( parser, argv[0], sb_out ); + builtin_print_help( parser, argv[0], stdout_buffer ); return 0; case L'?': @@ -432,11 +432,9 @@ static int builtin_ulimit( parser_t &parser, wchar_t ** argv ) } else { - sb_append( sb_err, - argv[0], - L": Too many arguments\n", - NULL ); - builtin_print_help( parser, argv[0], sb_err ); + stderr_buffer.append(argv[0]); + stderr_buffer.append(L": Too many arguments\n"); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } @@ -488,11 +486,11 @@ static int builtin_ulimit( parser_t &parser, wchar_t ** argv ) new_limit = wcstol( argv[woptind], &end, 10 ); if( errno || *end ) { - sb_printf( sb_err, + append_format(stderr_buffer, L"%ls: Invalid limit '%ls'\n", argv[0], argv[woptind] ); - builtin_print_help( parser, argv[0], sb_err ); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } new_limit *= get_multiplier( what ); @@ -503,11 +501,9 @@ static int builtin_ulimit( parser_t &parser, wchar_t ** argv ) default: { - sb_append( sb_err, - argv[0], - L": Too many arguments\n", - NULL ); - builtin_print_help( parser, argv[0], sb_err ); + stderr_buffer.append(argv[0]); + stderr_buffer.append(L": Too many arguments\n"); + builtin_print_help( parser, argv[0], stderr_buffer ); return 1; } diff --git a/common.cpp b/common.cpp index eb3bd582d..4e3fe7c7c 100644 --- a/common.cpp +++ b/common.cpp @@ -470,6 +470,13 @@ wcstring vformat_string(const wchar_t *format, va_list va_orig) return result; } +void append_format(wcstring &str, const wchar_t *format, ...) +{ + va_list va; + va_start( va, format ); + str.append(vformat_string(format, va)); + va_end( va ); +} wchar_t *wcsvarname( const wchar_t *str ) { @@ -648,14 +655,11 @@ ssize_t write_loop(int fd, const char *buff, size_t count) return out_cum; } - - void debug( int level, const wchar_t *msg, ... ) { va_list va; - string_buffer_t sb; - string_buffer_t sb2; + wcstring sb; int errno_old = errno; @@ -664,37 +668,117 @@ void debug( int level, const wchar_t *msg, ... ) CHECK( msg, ); - sb_init( &sb ); - sb_init( &sb2 ); + sb = format_string(L"%ls: ", program_name); + sb.append(vformat_string(msg, va)); - sb_printf( &sb, L"%ls: ", program_name ); - - va_start( va, msg ); - sb_vprintf( &sb, msg, va ); - va_end( va ); - - write_screen( (wchar_t *)sb.buff, &sb2 ); - fwprintf( stderr, L"%ls", sb2.buff ); - - sb_destroy( &sb ); - sb_destroy( &sb2 ); + wcstring sb2; + write_screen( sb, sb2 ); + fwprintf( stderr, L"%ls", sb2.c_str() ); errno = errno_old; } -void write_screen( const wchar_t *msg, string_buffer_t *buff ) +void write_screen( const wcstring &msg, wcstring &buff ) +{ + const wchar_t *start, *pos; + int line_width = 0; + int tok_width = 0; + int screen_width = common_get_width(); + + if( screen_width ) + { + start = pos = msg.c_str(); + while( 1 ) + { + int overflow = 0; + + tok_width=0; + + /* + Tokenize on whitespace, and also calculate the width of the token + */ + while( *pos && ( !wcschr( L" \n\r\t", *pos ) ) ) + { + + /* + Check is token is wider than one line. + If so we mark it as an overflow and break the token. + */ + if((tok_width + wcwidth(*pos)) > (screen_width-1)) + { + overflow = 1; + break; + } + + tok_width += wcwidth( *pos ); + pos++; + } + + /* + If token is zero character long, we don't do anything + */ + if( pos == start ) + { + start = pos = pos+1; + } + else if( overflow ) + { + /* + In case of overflow, we print a newline, except if we already are at position 0 + */ + wchar_t *token = wcsndup( start, pos-start ); + if( line_width != 0 ) + buff.push_back(L'\n'); + buff.append(format_string(L"%ls-\n", token)); + free( token ); + line_width=0; + } + else + { + /* + Print the token + */ + wchar_t *token = wcsndup( start, pos-start ); + if( (line_width + (line_width!=0?1:0) + tok_width) > screen_width ) + { + buff.push_back(L'\n'); + line_width=0; + } + buff.append(format_string(L"%ls%ls", line_width?L" ":L"", token )); + free( token ); + line_width += (line_width!=0?1:0) + tok_width; + } + + /* + Break on end of string + */ + if( !*pos ) + { + break; + } + + start=pos; + } + } + else + { + buff.append(msg); + } + buff.push_back(L'\n'); +} + +void write_screen( const wcstring &msg, string_buffer_t *buff ) { const wchar_t *start, *pos; int line_width = 0; int tok_width = 0; int screen_width = common_get_width(); - CHECK( msg, ); CHECK( buff, ); if( screen_width ) { - start = pos = msg; + start = pos = msg.c_str(); while( 1 ) { int overflow = 0; @@ -769,7 +853,7 @@ void write_screen( const wchar_t *msg, string_buffer_t *buff ) } else { - sb_printf( buff, L"%ls", msg ); + sb_printf( buff, L"%ls", msg.c_str() ); } sb_append_char( buff, L'\n' ); } @@ -1833,7 +1917,6 @@ void bugreport() _( L"This is a bug. Break on bugreport to debug." L"If you can reproduce it, please send a bug report to %s." ), PACKAGE_BUGREPORT ); - while (1) sleep(10000); } diff --git a/common.h b/common.h index 9ae0d789b..9e74dc307 100644 --- a/common.h +++ b/common.h @@ -351,6 +351,7 @@ void append_path_component(wcstring &path, const wcstring &component); wcstring format_string(const wchar_t *format, ...); wcstring vformat_string(const wchar_t *format, va_list va_orig); +void append_format(wcstring &str, const wchar_t *format, ...); /** Returns a newly allocated wide character string array equivalent of @@ -545,7 +546,8 @@ void common_handle_winch( int signal ); Write paragraph of output to the specified stringbuffer, and redo the linebreaks to fit the current screen. */ -void write_screen( const wchar_t *msg, string_buffer_t *buff ); +void write_screen( const wcstring &msg, string_buffer_t *buff ); +void write_screen( const wcstring &msg, wcstring &buff ); /** Tokenize the specified string into the specified wcstring_list_t. diff --git a/complete.cpp b/complete.cpp index 0f7f569fb..ab0dfa2dc 100644 --- a/complete.cpp +++ b/complete.cpp @@ -1853,7 +1853,7 @@ void complete( const wchar_t *cmd, argument to the specified stringbuffer, but only if arguemnt is non-null and longer than 0 characters. */ -static void append_switch( string_buffer_t *out, +static void append_switch( wcstring &out, const wcstring &opt, const wcstring &argument ) { @@ -1861,13 +1861,11 @@ static void append_switch( string_buffer_t *out, return; wcstring esc = escape_string( argument, 1 ); - sb_printf( out, L" --%ls %ls", opt.c_str(), esc.c_str() ); + append_format( out, L" --%ls %ls", opt.c_str(), esc.c_str() ); } -void complete_print( string_buffer_t *out ) +void complete_print( wcstring &out ) { - CHECK( out, ); - for (completion_entry_list_t::const_iterator iter = completion_entries.begin(); iter != completion_entries.end(); iter++) { const completion_entry_t *e = *iter; @@ -1883,7 +1881,7 @@ void complete_print( string_buffer_t *out ) } ; - sb_printf( out, + append_format( out, L"complete%ls", modestr[o->result_mode] ); @@ -1894,7 +1892,7 @@ void complete_print( string_buffer_t *out ) if( o->short_opt != 0 ) { - sb_printf( out, + append_format( out, L" --short-option '%lc'", o->short_opt ); } @@ -1916,7 +1914,7 @@ void complete_print( string_buffer_t *out ) L"condition", o->condition ); - sb_printf( out, L"\n" ); + out.append( L"\n" ); } } } diff --git a/complete.h b/complete.h index d0debf510..1abc94497 100644 --- a/complete.h +++ b/complete.h @@ -228,7 +228,7 @@ void complete( const wchar_t* cmd, std::vector &out); \param out The string_buffer_t to write completions to */ -void complete_print( string_buffer_t *out ); +void complete_print( wcstring &out ); /** Tests if the specified option is defined for the specified command diff --git a/exec.cpp b/exec.cpp index d4954388e..b5e5999f9 100644 --- a/exec.cpp +++ b/exec.cpp @@ -880,7 +880,7 @@ static pid_t exec_fork() /** Perform output from builtins */ -static void do_builtin_io( wchar_t *out, wchar_t *err ) +static void do_builtin_io( const wchar_t *out, const wchar_t *err ) { if( out ) @@ -1500,9 +1500,9 @@ void exec( parser_t &parser, job_t *j ) not inside a pipeline, there is no need to fork */ skip_fork = - ( !sb_out->used ) && - ( !sb_err->used ) && - ( !p->next ); + get_stdout_buffer().empty() && + get_stderr_buffer().empty() && + !p->next; /* If the output of a builtin is to be sent to an internal @@ -1513,15 +1513,14 @@ void exec( parser_t &parser, job_t *j ) io_data_t *io = io_get( j->io, 1 ); int buffer_stdout = io && io->io_mode == IO_BUFFER; - if( ( !sb_err->used ) && + if( ( get_stderr_buffer().empty() ) && ( !p->next ) && - ( sb_out->used ) && + ( ! get_stdout_buffer().empty() ) && ( buffer_stdout ) ) { - char *res = wcs2str( (wchar_t *)sb_out->buff ); - b_append( io->param2.out_buffer, res, strlen( res ) ); + std::string res = wcs2string( get_stdout_buffer() ); + b_append( io->param2.out_buffer, res.c_str(), res.size() ); skip_fork = 1; - free( res ); } for( io = j->io; io; io=io->next ) @@ -1560,8 +1559,8 @@ void exec( parser_t &parser, job_t *j ) */ p->pid = getpid(); setup_child_process( j, p ); - do_builtin_io( sb_out->used ? (wchar_t *)sb_out->buff : 0, sb_err->used ? (wchar_t *)sb_err->buff : 0 ); - + const wcstring &out = get_stdout_buffer(), &err = get_stderr_buffer(); + do_builtin_io( out.empty() ? NULL : out.c_str(), err.empty() ? NULL : err.c_str() ); exit( p->status ); } diff --git a/fish_tests.cpp b/fish_tests.cpp index e81a7c35e..21f5ded2b 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -108,42 +108,6 @@ static void err( const wchar_t *blah, ... ) wprintf( L"\n" ); } -/** - Stringbuffer test -*/ -static void sb_test() -{ - string_buffer_t b; - int res; - - sb_init( &b ); - - if( (res=sb_printf( &b, L"%ls%s", L"Testing ", "string_buffer_t " )) == -1 ) - { - err( L"Error %d while testing stringbuffers", res ); - } - - if( (res=sb_printf( &b, L"%ls", L"functionality" ))==-1) - { - err( L"Error %d while testing stringbuffers", res ); - } - - say( (wchar_t *)b.buff ); - - sb_clear( &b ); - - sb_printf( &b, L"%d %u %o %x %llX", -7, 99999999, 01234567, 0xdeadbeef, 0xdeadbeefdeadbeefll ); - if( wcscmp( (wchar_t *)b.buff, NUM_ANS) != 0 ) - { - err( L"numerical formating is broken, '%ls' != '%ls'", (wchar_t *)b.buff, NUM_ANS ); - } - else - say( L"numerical formating works" ); - - -} - - /** Test the escaping/unescaping code by escaping/unescaping random strings and verifying that the original string comes back. diff --git a/parser.cpp b/parser.cpp index 915210242..0dee481aa 100644 --- a/parser.cpp +++ b/parser.cpp @@ -360,7 +360,6 @@ parser_t::parser_t(enum parser_type_t type) : error_code(0), err_pos(0), current_tokenizer(NULL), - lineinfo(NULL), current_tokenizer_pos(0), job_start_pos(0), eval_level(-1), @@ -709,12 +708,7 @@ void parser_t::destroy() } } - if( lineinfo ) - { - sb_destroy( lineinfo ); - free(lineinfo ); - lineinfo = 0; - } + lineinfo.clear(); forbidden_function.clear(); @@ -726,21 +720,20 @@ void parser_t::destroy() \param target the buffer to write to \param prefix: The string token to prefix the ech line with. Usually the name of the command trying to parse something. */ -void parser_t::print_errors( string_buffer_t *target, const wchar_t *prefix ) +void parser_t::print_errors( wcstring &target, const wchar_t *prefix ) { - CHECK( target, ); CHECK( prefix, ); if( error_code && ! err_buff.empty() ) { int tmp; - sb_printf( target, L"%ls: %ls\n", prefix, err_buff.c_str() ); + append_format( target, L"%ls: %ls\n", prefix, err_buff.c_str() ); tmp = current_tokenizer_pos; current_tokenizer_pos = err_pos; - sb_printf( target, L"%ls", this->current_line() ); + append_format( target, L"%ls", this->current_line() ); current_tokenizer_pos=tmp; } @@ -849,14 +842,8 @@ int parser_t::eval_args( const wchar_t *line, std::vector &args ) return 1; } -void parser_t::stack_trace( block_t *b, string_buffer_t *buff) -{ - - /* - Validate input - */ - CHECK( buff, ); - +void parser_t::stack_trace( block_t *b, wcstring &buff) +{ /* Check if we should end the recursion */ @@ -869,9 +856,8 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff) This is an event handler */ wcstring description = event_get_desc( b->state1() ); - sb_printf( buff, _(L"in event handler: %ls\n"), description.c_str()); - sb_printf( buff, - L"\n" ); + append_format( buff, _(L"in event handler: %ls\n"), description.c_str()); + buff.append( L"\n" ); /* Stop recursing at event handler. No reason to belive that @@ -897,18 +883,18 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff) case SOURCE: { const wcstring &source_dest = b->state1(); - sb_printf( buff, _(L"in . (source) call of file '%ls',\n"), source_dest.c_str() ); + append_format( buff, _(L"in . (source) call of file '%ls',\n"), source_dest.c_str() ); break; } case FUNCTION_CALL: { const wcstring &function_call_name = b->state1(); - sb_printf( buff, _(L"in function '%ls',\n"), function_call_name.c_str() ); + append_format( buff, _(L"in function '%ls',\n"), function_call_name.c_str() ); break; } case SUBST: { - sb_printf( buff, _(L"in command substitution\n") ); + append_format( buff, _(L"in command substitution\n") ); break; } } @@ -917,14 +903,14 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff) if( file ) { - sb_printf( buff, + append_format( buff, _(L"\tcalled on line %d of file '%ls',\n"), b->src_lineno, file ); } else { - sb_printf( buff, + append_format( buff, _(L"\tcalled on standard input,\n") ); } @@ -940,14 +926,13 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff) { sb_append( &tmp, i>1?L" ":L"", process->argv(i), NULL ); } - sb_printf( buff, _(L"\twith parameter list '%ls'\n"), (wchar_t *)tmp.buff ); + append_format( buff, _(L"\twith parameter list '%ls'\n"), (wchar_t *)tmp.buff ); sb_destroy( &tmp ); } } - sb_printf( buff, - L"\n" ); + append_format( buff, L"\n" ); } /* @@ -1091,12 +1076,8 @@ const wchar_t *parser_t::current_line() if( !line ) return L""; - if( !lineinfo ) - { - lineinfo = (string_buffer_t *)malloc( sizeof(string_buffer_t) ); - sb_init( lineinfo ); - } - sb_clear( lineinfo ); + + lineinfo.clear(); /* Calculate line number, line offset, etc. @@ -1136,18 +1117,18 @@ const wchar_t *parser_t::current_line() */ if( !is_interactive || is_function() ) { - int prev_width = my_wcswidth( (wchar_t *)lineinfo->buff ); + int prev_width = my_wcswidth( lineinfo.c_str() ); if( file ) - sb_printf( lineinfo, + append_format( lineinfo, _(L"%ls (line %d): "), file, lineno ); else - sb_printf( lineinfo, + append_format( lineinfo, L"%ls: ", _(L"Standard input"), lineno ); - offset = my_wcswidth( (wchar_t *)lineinfo->buff ) - prev_width; + offset = my_wcswidth( lineinfo.c_str() ) - prev_width; } else { @@ -1164,7 +1145,7 @@ const wchar_t *parser_t::current_line() // Workaround since it seems impossible to print 0 copies of a character using %*lc if( offset+current_line_width ) { - sb_printf( lineinfo, + append_format( lineinfo, L"%ls\n%*lc^\n", line, offset+current_line_width, @@ -1172,7 +1153,7 @@ const wchar_t *parser_t::current_line() } else { - sb_printf( lineinfo, + append_format( lineinfo, L"%ls\n^\n", line ); } @@ -1181,7 +1162,7 @@ const wchar_t *parser_t::current_line() free( line ); parser_t::stack_trace( current_block, lineinfo ); - return (wchar_t *)lineinfo->buff; + return lineinfo.c_str(); } int parser_t::get_pos() const @@ -2560,7 +2541,7 @@ const wchar_t *parser_get_block_command( int type ) syntax errors in command substitutions, improperly escaped characters and improper use of the variable expansion operator. */ -int parser_t::parser_test_argument( const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset ) +int parser_t::parser_test_argument( const wchar_t *arg, wcstring *out, const wchar_t *prefix, int offset ) { wchar_t *unesc; wchar_t *pos; @@ -2588,7 +2569,7 @@ int parser_t::parser_test_argument( const wchar_t *arg, string_buffer_t *out, co error( SYNTAX_ERROR, offset, L"Mismatched parans" ); - this->print_errors( out, prefix); + this->print_errors( *out, prefix); } free( arg_cpy ); return 1; @@ -2634,7 +2615,7 @@ int parser_t::parser_test_argument( const wchar_t *arg, string_buffer_t *out, co error( SYNTAX_ERROR, offset, L"Invalid token '%ls'", arg_cpy ); - print_errors( out, prefix); + print_errors( *out, prefix); } return 1; } @@ -2660,7 +2641,7 @@ int parser_t::parser_test_argument( const wchar_t *arg, string_buffer_t *out, co if( out ) { expand_variable_error( *this, unesc, pos-unesc, offset ); - print_errors( out, prefix); + print_errors( *out, prefix); } } @@ -2677,8 +2658,7 @@ int parser_t::parser_test_argument( const wchar_t *arg, string_buffer_t *out, co } -int parser_t::test_args(const wchar_t * buff, - string_buffer_t *out, const wchar_t *prefix ) +int parser_t::test_args(const wchar_t * buff, wcstring *out, const wchar_t *prefix ) { tokenizer tok; tokenizer *previous_tokenizer = current_tokenizer; @@ -2717,7 +2697,7 @@ int parser_t::test_args(const wchar_t * buff, tok_get_pos( &tok ), TOK_ERR_MSG, tok_last(&tok) ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } err=1; do_loop=0; @@ -2732,7 +2712,7 @@ int parser_t::test_args(const wchar_t * buff, tok_get_pos( &tok ), UNEXPECTED_TOKEN_ERR_MSG, tok_get_desc( tok_last_type(&tok)) ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } err=1; do_loop=0; @@ -2753,7 +2733,7 @@ int parser_t::test_args(const wchar_t * buff, int parser_t::test( const wchar_t * buff, int *block_level, - string_buffer_t *out, + wcstring *out, const wchar_t *prefix ) { ASSERT_IS_MAIN_THREAD(); @@ -2851,7 +2831,7 @@ int parser_t::test( const wchar_t * buff, ILLEGAL_CMD_ERR_MSG, tok_last( &tok ) ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } break; } @@ -2873,7 +2853,7 @@ int parser_t::test( const wchar_t * buff, tok_get_pos( &tok ), COND_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -2909,11 +2889,13 @@ int parser_t::test( const wchar_t * buff, { if( count >= BLOCK_MAX_COUNT ) { - error( SYNTAX_ERROR, - tok_get_pos( &tok ), - BLOCK_ERR_MSG ); + if (out) { + error( SYNTAX_ERROR, + tok_get_pos( &tok ), + BLOCK_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); + } } else { @@ -2953,7 +2935,7 @@ int parser_t::test( const wchar_t * buff, tok_get_pos( &tok ), EXEC_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -2975,7 +2957,7 @@ int parser_t::test( const wchar_t * buff, tok_get_pos( &tok ), EXEC_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -2997,10 +2979,10 @@ int parser_t::test( const wchar_t * buff, tok_get_pos( &tok ), INVALID_CASE_ERR_MSG ); - print_errors( out, prefix); + print_errors( *out, prefix); const wcstring h = builtin_help_get( *this, L"case" ); if( h.size() ) - sb_printf( out, L"%ls", h.c_str() ); + append_format( *out, L"%ls", h.c_str() ); } } } @@ -3053,7 +3035,7 @@ int parser_t::test( const wchar_t * buff, error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_RETURN_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } } @@ -3111,7 +3093,7 @@ int parser_t::test( const wchar_t * buff, error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_LOOP_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } } @@ -3132,7 +3114,7 @@ int parser_t::test( const wchar_t * buff, tok_get_pos( &tok ), INVALID_ELSE_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -3149,10 +3131,10 @@ int parser_t::test( const wchar_t * buff, error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_END_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); const wcstring h = builtin_help_get( *this, L"end" ); if( h.size() ) - sb_printf( out, L"%ls", h.c_str() ); + append_format( *out, L"%ls", h.c_str() ); } } @@ -3197,7 +3179,7 @@ int parser_t::test( const wchar_t * buff, L"for", tok_last( &tok ) ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -3215,7 +3197,7 @@ int parser_t::test( const wchar_t * buff, BUILTIN_FOR_ERR_IN, L"for" ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } } @@ -3241,7 +3223,7 @@ int parser_t::test( const wchar_t * buff, error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_REDIRECTION_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } break; @@ -3258,7 +3240,7 @@ int parser_t::test( const wchar_t * buff, tok_get_pos( &tok ), CMD_ERR_MSG, tok_get_desc( tok_last_type(&tok))); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } needs_cmd=0; @@ -3293,7 +3275,7 @@ int parser_t::test( const wchar_t * buff, tok_get_desc( tok_last_type(&tok))); } - print_errors( out, prefix ); + print_errors( *out, prefix ); } } else if( forbid_pipeline ) @@ -3305,7 +3287,7 @@ int parser_t::test( const wchar_t * buff, tok_get_pos( &tok ), EXEC_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } else @@ -3342,7 +3324,7 @@ int parser_t::test( const wchar_t * buff, tok_get_desc( tok_last_type(&tok))); } - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -3369,7 +3351,7 @@ int parser_t::test( const wchar_t * buff, tok_last(&tok) ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -3395,7 +3377,7 @@ int parser_t::test( const wchar_t * buff, L"for", arg_count ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -3417,7 +3399,7 @@ int parser_t::test( const wchar_t * buff, tok_get_pos( &tok ), COND_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); } } @@ -3430,7 +3412,7 @@ int parser_t::test( const wchar_t * buff, block_pos[count-1], BLOCK_END_ERR_MSG ); - print_errors( out, prefix ); + print_errors( *out, prefix ); cmd = parser_get_block_command( block_type[count -1] ); if( cmd ) @@ -3438,7 +3420,7 @@ int parser_t::test( const wchar_t * buff, const wcstring h = builtin_help_get( *this, cmd ); if( h.size() ) { - sb_printf( out, L"%ls", h.c_str() ); + append_format( *out, L"%ls", h.c_str() ); } } diff --git a/parser.h b/parser.h index 727e171cf..9a5bad612 100644 --- a/parser.h +++ b/parser.h @@ -284,7 +284,7 @@ class parser_t { tokenizer *current_tokenizer; /** String for representing the current line */ - string_buffer_t *lineinfo; + wcstring lineinfo; /** This is the position of the beginning of the currently parsed command */ int current_tokenizer_pos; @@ -318,8 +318,8 @@ class parser_t { int parse_job( process_t *p, job_t *j, tokenizer *tok ); void skipped_exec( job_t * j ); void eval_job( tokenizer *tok ); - int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset ); - void print_errors( string_buffer_t *target, const wchar_t *prefix ); + int parser_test_argument( const wchar_t *arg, wcstring *out, const wchar_t *prefix, int offset ); + void print_errors( wcstring &target, const wchar_t *prefix ); void print_errors_stderr(); public: @@ -434,7 +434,7 @@ class parser_t { \param out if non-null, any errors in the command will be filled out into this buffer \param prefix the prefix string to prepend to each error message written to the \c out buffer */ - int test( const wchar_t * buff, int *block_level, string_buffer_t *out, const wchar_t *prefix ); + int test( const wchar_t * buff, int *block_level, wcstring *out, const wchar_t *prefix ); /** Test if the specified string can be parsed as an argument list, @@ -442,7 +442,7 @@ class parser_t { string contains errors, and the second bit is set if the string contains an unclosed block. */ - int test_args( const wchar_t * buff, string_buffer_t *out, const wchar_t *prefix ); + int test_args( const wchar_t * buff, wcstring *out, const wchar_t *prefix ); /** Tell the parser that the specified function may not be run if not @@ -481,9 +481,9 @@ class parser_t { const wchar_t *current_filename() const; /** - Write a stack trace starting at the specified block to the specified string_buffer_t + Write a stack trace starting at the specified block to the specified wcstring */ - void stack_trace( block_t *b, string_buffer_t *buff); + void stack_trace( block_t *b, wcstring &buff); int get_block_type( const wchar_t *cmd ) const; const wchar_t *get_block_command( int type ) const; diff --git a/reader.cpp b/reader.cpp index 860ddcee4..bbf6b608f 100644 --- a/reader.cpp +++ b/reader.cpp @@ -2219,8 +2219,7 @@ int reader_shell_test( const wchar_t *b ) if( res & PARSER_TEST_ERROR ) { - string_buffer_t sb; - sb_init( &sb ); + wcstring sb; int tmp[1]; int tmp2[1]; @@ -2228,8 +2227,7 @@ int reader_shell_test( const wchar_t *b ) s_write( &data->screen, L"", L"", tmp, tmp2, 0 ); parser_t::principal_parser().test( b, 0, &sb, L"fish" ); - fwprintf( stderr, L"%ls", sb.buff ); - sb_destroy( &sb ); + fwprintf( stderr, L"%ls", sb.c_str() ); } return res; } @@ -3395,20 +3393,16 @@ static int read_ni( int fd, io_data_t *io ) if( str ) { - string_buffer_t sb; - sb_init( &sb ); - + wcstring sb; if( ! parser.test( str, 0, &sb, L"fish" ) ) { parser.eval( str, io, TOP ); } else { - fwprintf( stderr, L"%ls", sb.buff ); + fwprintf( stderr, L"%ls", sb.c_str() ); res = 1; } - sb_destroy( &sb ); - free( str ); } else