/// Define a function. Calls into `function.cpp` to perform the heavy lifting of defining a /// function. int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_list_t &c_args, const wcstring &contents, int definition_line_offset) { // The wgetopt function expects 'function' as the first argument. Make a new wcstring_list with // that property. This is needed because this builtin has a different signature than the other // builtins. wcstring_list_t args = {L"function"}; args.insert(args.end(), c_args.begin(), c_args.end()); // Hackish const_cast matches the one in builtin_run. const null_terminated_array_t<wchar_t> argv_array(args); wchar_t **argv = const_cast<wchar_t **>(argv_array.get()); wchar_t *cmd = argv[0]; int argc = builtin_count_args(argv); // A valid function name has to be the first argument. wcstring function_name; int retval = validate_function_name(argc, argv, function_name, cmd, streams); if (retval != STATUS_CMD_OK) return retval; argv++; argc--; function_cmd_opts_t opts; int optind; retval = parse_cmd_opts(opts, &optind, argc, argv, parser, streams); if (retval != STATUS_CMD_OK) return retval; if (opts.print_help) { builtin_print_help(parser, streams, cmd, streams.err); return STATUS_CMD_OK; } if (argc != optind) { if (opts.named_arguments.size()) { for (int i = optind; i < argc; i++) { opts.named_arguments.push_back(argv[i]); } } else { streams.err.append_format(_(L"%ls: Unexpected positional argument '%ls'"), cmd, argv[optind]); return STATUS_INVALID_ARGS; } } // We have what we need to actually define the function. function_data_t d; d.name = function_name; if (!opts.description.empty()) d.description = opts.description; // d.description = opts.description; d.events.swap(opts.events); d.shadow_scope = opts.shadow_scope; d.named_arguments.swap(opts.named_arguments); d.inherit_vars.swap(opts.inherit_vars); for (size_t i = 0; i < d.events.size(); i++) { event_t &e = d.events.at(i); e.function_name = d.name; } d.definition = contents.c_str(); function_add(d, parser, definition_line_offset); // Handle wrap targets by creating the appropriate completions. for (size_t w = 0; w < opts.wrap_targets.size(); w++) { complete_add_wrapper(function_name, opts.wrap_targets.at(w)); } return STATUS_CMD_OK; }
/// Define a function. Calls into `function.cpp` to perform the heavy lifting of defining a /// function. int builtin_function(parser_t &parser, io_streams_t &streams, const wcstring_list_t &c_args, const parsed_source_ref_t &source, tnode_t<grammar::job_list> body) { assert(source && "Missing source in builtin_function"); // The wgetopt function expects 'function' as the first argument. Make a new wcstring_list with // that property. This is needed because this builtin has a different signature than the other // builtins. wcstring_list_t args = {L"function"}; args.insert(args.end(), c_args.begin(), c_args.end()); null_terminated_array_t<wchar_t> argv_array(args); wchar_t **argv = argv_array.get(); wchar_t *cmd = argv[0]; int argc = builtin_count_args(argv); // A valid function name has to be the first argument. wcstring function_name; int retval = validate_function_name(argc, argv, function_name, cmd, streams); if (retval != STATUS_CMD_OK) return retval; argv++; argc--; function_cmd_opts_t opts; int optind; retval = parse_cmd_opts(opts, &optind, argc, argv, parser, streams); if (retval != STATUS_CMD_OK) return retval; if (opts.print_help) { builtin_print_help(parser, streams, cmd, streams.err); return STATUS_CMD_OK; } if (argc != optind) { if (opts.named_arguments.size()) { for (int i = optind; i < argc; i++) { opts.named_arguments.push_back(argv[i]); } } else { streams.err.append_format(_(L"%ls: Unexpected positional argument '%ls'"), cmd, argv[optind]); return STATUS_INVALID_ARGS; } } // We have what we need to actually define the function. function_data_t d; d.name = function_name; if (!opts.description.empty()) d.description = opts.description; // d.description = opts.description; d.events.swap(opts.events); d.props.shadow_scope = opts.shadow_scope; d.props.named_arguments = std::move(opts.named_arguments); d.inherit_vars = std::move(opts.inherit_vars); for (size_t i = 0; i < d.events.size(); i++) { event_t &e = d.events.at(i); e.function_name = d.name; } d.props.parsed_source = source; d.props.body_node = body; function_add(std::move(d), parser); // Handle wrap targets by creating the appropriate completions. for (const wcstring &wt : opts.wrap_targets) complete_add_wrapper(function_name, wt); return STATUS_CMD_OK; }