Example #1
0
// Check if the first argument under the given node is --help
static bool first_argument_is_help(const parse_node_tree_t &node_tree, const parse_node_t &node, const wcstring &src)
{
    bool is_help = false;
    const parse_node_tree_t::parse_node_list_t arg_nodes = node_tree.find_nodes(node, symbol_argument, 1);
    if (! arg_nodes.empty())
    {
        // Check the first argument only
        const parse_node_t &arg = *arg_nodes.at(0);
        const wcstring first_arg_src = arg.get_source(src);
        is_help = parse_util_argument_is_help(first_arg_src.c_str(), 3);
    }
    return is_help;
}
Example #2
0
static void prettify_node_recursive(const wcstring &source, const parse_node_tree_t &tree, node_offset_t node_idx, indent_t node_indent, parse_token_type_t parent_type, bool *has_new_line, wcstring *out_result, bool do_indent)
{
    const parse_node_t &node = tree.at(node_idx);
    const parse_token_type_t node_type = node.type;

    /* Increment the indent if we are either a root job_list, or root case_item_list, or in an if or while header (#1665) */
    const bool is_root_job_list = (node_type == symbol_job_list && parent_type != symbol_job_list);
    const bool is_root_case_item_list = (node_type == symbol_case_item_list && parent_type != symbol_case_item_list);
    const bool is_if_while_header = ((node_type == symbol_job || node_type == symbol_andor_job_list) &&
                                    (parent_type == symbol_if_clause || parent_type == symbol_while_header));
    if (is_root_job_list || is_root_case_item_list || is_if_while_header)
    {
        node_indent += 1;
    }

    /* Handle comments, which come before the text */
    if (node.has_comments())
    {
        const parse_node_tree_t::parse_node_list_t comment_nodes = tree.comment_nodes_for_node(node);
        for (size_t i=0; i < comment_nodes.size(); i++)
        {
            const parse_node_t &comment_node = *comment_nodes.at(i);
            append_whitespace(node_indent, do_indent, *has_new_line, out_result);
            out_result->append(source, comment_node.source_start, comment_node.source_length);
        }
    }

    if (node_type == parse_token_type_end)
    {
        /* Newline */
        out_result->push_back(L'\n');
        *has_new_line = true;
    }
    else if ((node_type >= FIRST_PARSE_TOKEN_TYPE && node_type <= LAST_PARSE_TOKEN_TYPE) || node_type == parse_special_type_parse_error)
    {
        if (node.has_source())
        {
            /* Some type representing a particular token */
            append_whitespace(node_indent, do_indent, *has_new_line, out_result);
            out_result->append(source, node.source_start, node.source_length);
            *has_new_line = false;
        }
    }

    /* Recurse to all our children */
    for (node_offset_t idx = 0; idx < node.child_count; idx++)
    {
        /* Note we pass our type to our child, which becomes its parent node type */
        prettify_node_recursive(source, tree, node.child_start + idx, node_indent, node_type, has_new_line, out_result, do_indent);
    }
}
static void prettify_node_recursive(const wcstring &source, const parse_node_tree_t &tree,
                                    node_offset_t node_idx, indent_t node_indent,
                                    parse_token_type_t parent_type, bool *has_new_line,
                                    wcstring *out_result, bool do_indent) {
    const parse_node_t &node = tree.at(node_idx);
    const parse_token_type_t node_type = node.type;
    const parse_token_type_t prev_node_type =
        node_idx > 0 ? tree.at(node_idx - 1).type : token_type_invalid;

    // Increment the indent if we are either a root job_list, or root case_item_list, or in an if or
    // while header (#1665).
    const bool is_root_job_list = node_type == symbol_job_list && parent_type != symbol_job_list;
    const bool is_root_case_list =
        node_type == symbol_case_item_list && parent_type != symbol_case_item_list;
    const bool is_if_while_header =
        (node_type == symbol_job || node_type == symbol_andor_job_list) &&
        (parent_type == symbol_if_clause || parent_type == symbol_while_header);

    if (is_root_job_list || is_root_case_list || is_if_while_header) {
        node_indent += 1;
    }

    if (dump_parse_tree) dump_node(node_indent, node, source);

    if (node.has_comments())  // handle comments, which come before the text
    {
        const parse_node_tree_t::parse_node_list_t comment_nodes =
            (tree.comment_nodes_for_node(node));
        for (size_t i = 0; i < comment_nodes.size(); i++) {
            const parse_node_t &comment_node = *comment_nodes.at(i);
            append_whitespace(node_indent, do_indent, *has_new_line, out_result);
            out_result->append(source, comment_node.source_start, comment_node.source_length);
        }
    }

    if (node_type == parse_token_type_end) {
        out_result->push_back(L'\n');
        *has_new_line = true;
    } else if ((node_type >= FIRST_PARSE_TOKEN_TYPE && node_type <= LAST_PARSE_TOKEN_TYPE) ||
               node_type == parse_special_type_parse_error) {
        if (node.keyword != parse_keyword_none) {
            append_whitespace(node_indent, do_indent, *has_new_line, out_result);
            out_result->append(keyword_description(node.keyword));
            *has_new_line = false;
        } else if (node.has_source()) {
            // Some type representing a particular token.
            if (prev_node_type != parse_token_type_redirection) {
                append_whitespace(node_indent, do_indent, *has_new_line, out_result);
            }
            out_result->append(source, node.source_start, node.source_length);
            *has_new_line = false;
        }
    }

    // Recurse to all our children.
    for (node_offset_t idx = 0; idx < node.child_count; idx++) {
        // Note: We pass our type to our child, which becomes its parent node type.
        // Note: While node.child_start could be -1 (NODE_OFFSET_INVALID) the addition is safe
        // because we won't execute this call in that case since node.child_count should be zero.
        prettify_node_recursive(source, tree, node.child_start + idx, node_indent, node_type,
                                has_new_line, out_result, do_indent);
    }
}