diff --git a/builtin.cpp b/builtin.cpp index c0372812c..fa187a17f 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -1086,7 +1086,8 @@ static int builtin_generic( parser_t &parser, wchar_t **argv ) static void functions_def( const wcstring &name, wcstring &out ) { const wchar_t *desc = function_get_desc( name ); - const wchar_t *def = function_get_definition(name); + wcstring def; + function_get_definition(name, &def); event_t search(EVENT_ANY); @@ -1169,11 +1170,10 @@ static void functions_def( const wcstring &name, wcstring &out ) /* This forced tab is sort of crummy - not all functions start with a tab */ - append_format( out, L"\n\t%ls", def); + append_format( out, L"\n\t%ls", def.c_str()); /* Append a newline before the 'end', unless there already is one there */ - size_t deflen = wcslen(def); - if (deflen == 0 || def[deflen-1] != L'\n') { + if (! string_suffixes_string(L"\n", def)) { out.push_back(L'\n'); } out.append(L"end\n"); @@ -3733,10 +3733,14 @@ void builtin_get_names(std::vector &list) { } } -const wchar_t *builtin_get_desc( const wcstring &name ) +wcstring builtin_get_desc( const wcstring &name ) { + wcstring result; const builtin_data_t *builtin = builtin_lookup(name); - return builtin ? _(builtin->desc) : NULL; + if (builtin) { + result = _(builtin->desc); + } + return result; } void builtin_push_io( parser_t &parser, int in ) diff --git a/builtin.h b/builtin.h index f2093780b..a34c83cbb 100644 --- a/builtin.h +++ b/builtin.h @@ -155,9 +155,9 @@ void builtin_pop_io(parser_t &parser); /** - Return a one-line description of the specified builtin. This is usually a truly constant string, so we should not wrap it in a wcstring. + Return a one-line description of the specified builtin. */ -const wchar_t *builtin_get_desc( const wcstring &b ); +wcstring builtin_get_desc( const wcstring &b ); /** diff --git a/complete.cpp b/complete.cpp index 2a051b397..35e0a5ebf 100644 --- a/complete.cpp +++ b/complete.cpp @@ -832,7 +832,7 @@ int complete_is_valid_argument( const wchar_t *str, static void complete_strings( std::vector &comp_out, const wcstring &wc_escaped, const wchar_t *desc, - const wchar_t *(*desc_func)(const wcstring &), + wcstring (*desc_func)(const wcstring &), std::vector &possible_comp, complete_flags_t flags ) { @@ -981,16 +981,20 @@ void completer_t::complete_cmd_desc( const wcstring &str ) } /** - Returns a description for the specified function + Returns a description for the specified function, or an empty string if none */ -static const wchar_t *complete_function_desc( const wcstring &fn ) +static wcstring complete_function_desc( const wcstring &fn ) { + wcstring result; + const wchar_t *res = function_get_desc( fn ); + if (res) { + result = res; + } else { + function_get_definition(fn, &result); + } - if( !res ) - res = function_get_definition( fn ); - - return res; + return result; } diff --git a/exec.cpp b/exec.cpp index f8689840f..92b2a476a 100644 --- a/exec.cpp +++ b/exec.cpp @@ -787,12 +787,13 @@ void exec( parser_t &parser, job_t *j ) */ signal_unblock(); - const wchar_t * orig_def = function_get_definition( p->argv0() ); + wcstring orig_def; + function_get_definition( p->argv0(), &orig_def ); // function_get_named_arguments may trigger autoload, which deallocates the orig_def. // We should make function_get_definition return a wcstring (but how to handle NULL...) - if (orig_def) - def = wcsdup(orig_def); + if (! orig_def.empty()) + def = wcsdup(orig_def.c_str()); wcstring_list_t named_arguments = function_get_named_arguments( p->argv0() ); shadows = function_get_shadows( p->argv0() ); diff --git a/function.cpp b/function.cpp index 5b80391b8..166d30a55 100644 --- a/function.cpp +++ b/function.cpp @@ -251,10 +251,13 @@ shared_ptr function_get(const wcstring &name) } } -const wchar_t *function_get_definition( const wcstring &name ) +bool function_get_definition( const wcstring &name, wcstring *out_definition ) { shared_ptr func = function_get(name); - return func ? func->definition.c_str() : NULL; + if (func && out_definition) { + out_definition->assign(func->definition); + } + return func != NULL; } wcstring_list_t function_get_named_arguments( const wcstring &name ) diff --git a/function.h b/function.h index 4bf4003f7..01f5653bc 100644 --- a/function.h +++ b/function.h @@ -103,14 +103,10 @@ void function_add( const function_data_t &data, const parser_t &parser ); void function_remove( const wcstring &name ); /** - Gets a function by name. + Returns by reference the definition of the function with the name \c name. + Returns true if successful, false if no function with the given name exists. */ -shared_ptr function_get(const wcstring &name); - -/** - Returns the definition of the function with the name \c name. -*/ -const wchar_t *function_get_definition( const wcstring &name ); +bool function_get_definition( const wcstring &name, wcstring *out_definition ); /** Returns the description of the function with the name \c name. diff --git a/history.cpp b/history.cpp index 935b2eab5..547792f45 100644 --- a/history.cpp +++ b/history.cpp @@ -136,18 +136,6 @@ static void escape_yaml(std::string &str); /** Undoes escape_yaml */ static void unescape_yaml(std::string &str); -/* Custom deleter for our shared_ptr */ -class history_item_data_deleter_t { - private: - const bool free_it; - public: - history_item_data_deleter_t(bool flag) : free_it(flag) { } - void operator()(const wchar_t *data) { - if (free_it) - free((void *)data); - } -}; - /* We can merge two items if they are the same command. We use the more recent timestamp and the longer list of required paths. */ bool history_item_t::merge(const history_item_t &item) { diff --git a/wildcard.cpp b/wildcard.cpp index e9055f9be..e27efe593 100644 --- a/wildcard.cpp +++ b/wildcard.cpp @@ -204,7 +204,7 @@ static bool wildcard_complete_internal(const wcstring &orig, const wchar_t *wc, bool is_first, const wchar_t *desc, - const wchar_t *(*desc_func)(const wcstring &), + wcstring (*desc_func)(const wcstring &), std::vector &out, int flags ) { @@ -245,8 +245,8 @@ static bool wildcard_complete_internal(const wcstring &orig, it. If it returns something, use that as the description. */ - const wchar_t *func_desc = desc_func( orig ); - if( func_desc ) + wcstring func_desc = desc_func( orig ); + if (! func_desc.empty()) out_desc = func_desc; } @@ -300,7 +300,7 @@ static bool wildcard_complete_internal(const wcstring &orig, bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc, - const wchar_t *(*desc_func)(const wcstring &), + wcstring (*desc_func)(const wcstring &), std::vector &out, int flags ) { diff --git a/wildcard.h b/wildcard.h index cf7aa10f0..40830f0cc 100644 --- a/wildcard.h +++ b/wildcard.h @@ -89,7 +89,7 @@ int wildcard_has( const wchar_t *str, int internal ); bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc, - const wchar_t *(*desc_func)(const wcstring &), + wcstring (*desc_func)(const wcstring &), std::vector &out, expand_flags_t flags );