Clean up of get_function_name

Have it return a real string, instead of a pointer with uncertain
lifetime.
This commit is contained in:
ridiculousfish
2021-07-15 11:21:32 -07:00
parent bad1b84513
commit ccd1b4e4f4
4 changed files with 23 additions and 32 deletions

View File

@@ -433,10 +433,11 @@ static int parse_cmd_opts(argparse_cmd_opts_t &opts, int *optind, //!OCLINT(hig
if (opts.name.empty()) { if (opts.name.empty()) {
// If no name has been given, we default to the function name. // If no name has been given, we default to the function name.
// If any error happens, the backtrace will show which argparse it was. // If any error happens, the backtrace will show which argparse it was.
const wchar_t *fn = parser.get_function_name(1); if (maybe_t<wcstring> fn = parser.get_function_name(1)) {
opts.name = fn.acquire();
if (!fn) fn = L"argparse"; } else {
opts.name = fn; opts.name = L"argparse";
}
} }
*optind = w.woptind; *optind = w.woptind;

View File

@@ -381,10 +381,8 @@ maybe_t<int> builtin_status(parser_t &parser, io_streams_t &streams, const wchar
} }
case STATUS_FUNCTION: { case STATUS_FUNCTION: {
CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd)
const wchar_t *fn = parser.get_function_name(opts.level); maybe_t<wcstring> fn = parser.get_function_name(opts.level);
streams.out.append_format(L"%ls\n", fn ? fn->c_str() : _(L"Not a function"));
if (!fn) fn = _(L"Not a function");
streams.out.append_format(L"%ls\n", fn);
break; break;
} }
case STATUS_LINE_NUMBER: { case STATUS_LINE_NUMBER: {

View File

@@ -412,26 +412,19 @@ wcstring parser_t::stack_trace() const {
return trace; return trace;
} }
/// Returns the name of the currently evaluated function if we are currently evaluating a function, bool parser_t::is_function() const {
/// NULL otherwise. This is tested by moving down the block-scope-stack, checking every block if it
/// is of type FUNCTION_CALL. If the caller doesn't specify a starting position in the stack we
/// begin with the current block.
const wchar_t *parser_t::is_function() const {
for (const auto &b : block_list) { for (const auto &b : block_list) {
if (b.is_function_call()) { if (b.is_function_call()) {
return b.function_name.c_str(); return true;
} else if (b.type() == block_type_t::source) { } else if (b.type() == block_type_t::source) {
// If a function sources a file, obviously that function's offset doesn't // If a function sources a file, don't descend further.
// contribute.
break; break;
} }
} }
return nullptr; return false;
} }
/// Return the function name for the specified stack frame. Default is zero (current frame). maybe_t<wcstring> parser_t::get_function_name(int level) {
/// The special value zero means the function frame immediately above the closest breakpoint frame.
const wchar_t *parser_t::get_function_name(int level) {
if (level == 0) { if (level == 0) {
// Return the function name for the level preceding the most recent breakpoint. If there // Return the function name for the level preceding the most recent breakpoint. If there
// isn't one return the function name for the current level. // isn't one return the function name for the current level.
@@ -441,13 +434,10 @@ const wchar_t *parser_t::get_function_name(int level) {
if (b.type() == block_type_t::breakpoint) { if (b.type() == block_type_t::breakpoint) {
found_breakpoint = true; found_breakpoint = true;
} else if (found_breakpoint && b.is_function_call()) { } else if (found_breakpoint && b.is_function_call()) {
return b.function_name.c_str(); return b.function_name;
} }
} }
return nullptr; // couldn't find a breakpoint frame return none(); // couldn't find a breakpoint frame
} else if (level == 1) {
// Return the function name for the current level.
return this->is_function();
} }
// Level 1 is the topmost function call. Level 2 is its caller. Etc. // Level 1 is the topmost function call. Level 2 is its caller. Etc.
@@ -456,11 +446,15 @@ const wchar_t *parser_t::get_function_name(int level) {
if (b.is_function_call()) { if (b.is_function_call()) {
funcs_seen++; funcs_seen++;
if (funcs_seen == level) { if (funcs_seen == level) {
return b.function_name.c_str(); return b.function_name;
} }
} else if (b.type() == block_type_t::source && level == 1) {
// Historical: If we want the topmost function, but we are really in a file sourced by a
// function, don't consider ourselves to be in a function.
break;
} }
} }
return nullptr; // couldn't find that function level return none();
} }
int parser_t::get_lineno() const { int parser_t::get_lineno() const {

View File

@@ -282,10 +282,8 @@ class parser_t : public std::enable_shared_from_this<parser_t> {
/// Adds a job to the beginning of the job list. /// Adds a job to the beginning of the job list.
void job_add(shared_ptr<job_t> job); void job_add(shared_ptr<job_t> job);
/// Returns the name of the currently evaluated function if we are currently evaluating a /// \return whether we are currently evaluating a function.
/// function, null otherwise. This is tested by moving down the block-scope-stack, checking bool is_function() const;
/// every block if it is of type FUNCTION_CALL.
const wchar_t *is_function() const;
/// Create a parser. /// Create a parser.
parser_t(); parser_t();
@@ -394,7 +392,7 @@ class parser_t : public std::enable_shared_from_this<parser_t> {
static const wchar_t *get_block_desc(block_type_t block); static const wchar_t *get_block_desc(block_type_t block);
/// Return the function name for the specified stack frame. Default is one (current frame). /// Return the function name for the specified stack frame. Default is one (current frame).
const wchar_t *get_function_name(int level = 1); maybe_t<wcstring> get_function_name(int level = 1);
/// Promotes a job to the front of the list. /// Promotes a job to the front of the list.
void job_promote(job_t *job); void job_promote(job_t *job);