From patchwork Thu Mar 25 21:51:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Giuliano Procida X-Patchwork-Id: 42775 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 375283857C6B; Thu, 25 Mar 2021 21:52:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 375283857C6B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1616709130; bh=qwIx8x66TcLFTiJLDjfQgXN7KsJo/u7dvgGZOh5NFQc=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=rAsmFB9pyaol3JF7hPqvDJFq2rMhodIy8lV/JBzc3BFheoXUIvO4U3uAVbII40DmE hXBJesGOsKQZoXP29XJb+2/v2nflX6aPWs0u5KT+owM9iy2lwtzYJrKNefnV3wHRdq ox8B9jCKHN27pEIJp2tzFzZRubGXbUj6UXSQdR7U= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by sourceware.org (Postfix) with ESMTPS id B94033857C62 for ; Thu, 25 Mar 2021 21:52:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B94033857C62 Received: by mail-qt1-x849.google.com with SMTP id m8so4100470qtp.14 for ; Thu, 25 Mar 2021 14:52:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=qwIx8x66TcLFTiJLDjfQgXN7KsJo/u7dvgGZOh5NFQc=; b=L2mI7PW4dhLcE85pi9NdEWjoaQ3Pbmrkg9AUrNouqM2H5gjeZ/ujolyBeALNv1i12e GmXmpvtzN+FRFpyI+8XIJhz37s51zW0c1Vya36yl38SMCoKRk1rlbcNEmP4D8vmnOoK6 mkhVH1XGPsdp8wAjlLK0Tj7xCAjwJvM/nFRQXIKCCyILhOyBbllSRF7X3AH8SCP+xuez kqYu9cSRp+7fYhrfN9lj5Mo0DWfYVCzB+M/zr0NhpF+6OQXG8e8nMroDf6TaE57VR/9a WuaP0FftwbIuCIESxFykLkbK6nKzcGnu3CuAO2pwhnRgf536XoqQefJnWGhIS4DGyHk7 bnrg== X-Gm-Message-State: AOAM5323eljSL+X51RtHP9qe3B/sViDk5KcozklG5W6CimA6PKh0SjlH 5iock3gxZXa2AWagBqGb1JC85c6XEVp9X+DIWK5Ecw81TPyvtrZtEgIy2k9S8GqaEtv6Rvto84r Nz9YuVZ8wInI0IszkcjjFfbsaX01/E1g960n5Nd0lL2EMmfoPgdHP+Tnt1j8odPPf4ZhtOfw= X-Google-Smtp-Source: ABdhPJzkAdOcjQ4RYRNsb9475ZCrl47g/EfR78dxKrR6sT0sFuPx+uQpES7VNek5sfWUc5oi/LE3OxXC+ZKBwg== X-Received: from tef.lon.corp.google.com ([2a00:79e0:d:110:2df6:f24a:7f54:86a8]) (user=gprocida job=sendgmr) by 2002:a05:6214:18e5:: with SMTP id ep5mr10799403qvb.32.1616709127287; Thu, 25 Mar 2021 14:52:07 -0700 (PDT) Date: Thu, 25 Mar 2021 21:51:39 +0000 In-Reply-To: <20210325215146.3597963-1-gprocida@google.com> Message-Id: <20210325215146.3597963-3-gprocida@google.com> Mime-Version: 1.0 References: <20210316165509.2658452-1-gprocida@google.com> <20210325215146.3597963-1-gprocida@google.com> X-Mailer: git-send-email 2.31.0.291.g576ba9dcdaf-goog Subject: [RFC PATCH 2/9] Add pass to drop empty XML elements To: libabigail@sourceware.org X-Spam-Status: No, score=-22.3 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: Giuliano Procida via Libabigail From: Giuliano Procida Reply-To: Giuliano Procida Cc: maennich@google.com, kernel-team@android.com Errors-To: libabigail-bounces@sourceware.org Sender: "Libabigail" Certain elements in ABI XML are effectvely containers and can be dropped if empty and their attributes don't carry ABI information. - elf-variable-symbols: pure container - elf-function-symbols: pure container - namespace-decl: has a name - abi-instr: compilation unit (path etc.) - abi-corpus: binary object (architecture) - abi-corpus-group: binary objects (architecture) It could be argued that abi-corpus (or abi-corpus-group) should be kept around to hold the architecture of an object or set of objects. However, if a binary object has no symbols (say, if it is empty), it hardly matters what the architecture is. Note that: - abidiff rejects XML files with an XML declaration at the top - abidiff rejects completely empty files Resolving the first would make the second moot. In the meantime, we avoid dropping top-level elements. * scripts/abitidy.pl (drop_if_empty): New variable containing the tags of elements that can be dropped if empty. (drop_empty): New Function that removes empty elements, except top-level ones. Signed-off-by: Giuliano Procida --- scripts/abitidy.pl | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/scripts/abitidy.pl b/scripts/abitidy.pl index 66d636d7..1f74e267 100755 --- a/scripts/abitidy.pl +++ b/scripts/abitidy.pl @@ -105,20 +105,58 @@ sub indent($indent, $node) { } } +# Remove an XML element and any preceeding comment. +sub remove_node($node) { + my $prev = $node->previousSibling(); + if ($prev && $prev->nodeType == XML_COMMENT_NODE) { + $prev->unbindNode(); + } + $node->unbindNode(); +} + +# These container elements can be dropped if empty. +my %drop_if_empty = map { $_ => undef } qw( + elf-variable-symbols + elf-function-symbols + namespace-decl + abi-instr + abi-corpus + abi-corpus-group +); + +# This is a XML DOM traversal as we want post-order traversal so we +# delete nodes that become empty during the process. +sub drop_empty; +sub drop_empty($node) { + my $node_name = $node->getName(); + for my $child ($node->childNodes()) { + drop_empty($child); + } + if (!$node->hasChildNodes() && $node->nodeType == XML_ELEMENT_NODE && exists $drop_if_empty{$node->getName()}) { + # Until abidiff accepts empty ABIs, avoid dropping top-level elements. + if ($node->parentNode->nodeType == XML_ELEMENT_NODE) { + remove_node($node); + } + } +} + # Parse arguments. my $input_opt; my $output_opt; my $all_opt; +my $drop_opt; GetOptions('i|input=s' => \$input_opt, 'o|output=s' => \$output_opt, 'a|all' => sub { - 1 + $drop_opt = 1 }, + 'd|drop-empty!' => \$drop_opt, ) and !@ARGV or die("usage: $0", map { (' ', $_) } ( '[-i|--input file]', '[-o|--output file]', '[-a|--all]', + '[-d|--[no-]drop-empty]', ), "\n"); exit 0 unless defined $input_opt; @@ -131,6 +169,9 @@ close $input; # This simplifies DOM analysis and manipulation. strip_text($dom); +# Drop empty elements. +drop_empty($dom) if $drop_opt; + exit 0 unless defined $output_opt; # Reformat for human consumption.