From patchwork Wed Jul 1 13:19:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Giuliano Procida X-Patchwork-Id: 39859 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 D04CF3851C16; Wed, 1 Jul 2020 13:19:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D04CF3851C16 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593609565; bh=/bjA8DEMZn9CgUNV/D2mtlp1u5zmzlmdp7/AN0Py+n8=; h=Date:In-Reply-To:References:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:Cc:From; b=ZUMP446wo73zDmmPc7D2LiM9y7rnNfP3bcbxfei2we96V4/abhQZaJ/UpsSj1UrX4 sCEUawA+pOwLaNIGLANGOQl5ZfMece1FiMLw8CZdB0oQpCTKQ+xZS8oXnAchYo8SWV QBve3+kqQeu9SafBoFLXFNczCDjl0YSeAcAe8hCc= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mail-wr1-x449.google.com (mail-wr1-x449.google.com [IPv6:2a00:1450:4864:20::449]) by sourceware.org (Postfix) with ESMTPS id A92223857007 for ; Wed, 1 Jul 2020 13:19:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org A92223857007 Received: by mail-wr1-x449.google.com with SMTP id c18so13067482wrp.15 for ; Wed, 01 Jul 2020 06:19:21 -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=/bjA8DEMZn9CgUNV/D2mtlp1u5zmzlmdp7/AN0Py+n8=; b=Bm1xktKbMliPU6qkjjFFXc8MuzOLbKzBlHydU4kGb/q4HudMYNmewHj0uKXKhNVAwt GQnY0O/vrCKYVqN/7+VMoxymNi/emgCzckglsZF7kKp0cY5V+WKwwzM+hsJoGkXHyIuL YOPLpsvzPoP0oPwSexLV22fQLn2opitUk3EXHU27ZQu5bxAeh7K4oz08c6571LtPM9IC 4DCuQgZV6+7Vvc41HtbhvOM607P0saWEaAvgdTw3pjQF2NJLY++XjV7O5ZeBm1VLEnDR ZL81phVgk99ERW7CZT+xHIx1a8PAd/wMgwXIKkdQs3wpOT52GyaAncAwr7GSxFv4CYeS LKUw== X-Gm-Message-State: AOAM530WEe0lpelAGVpvfEtvw1+wsTOPXzH/63kL0P8wG9wlenC8Zbkp BeclkbUdmuSgRtP1suiPpYDy10/3egkljQz6MXJLod7Ays1xJyHtMKpbmwTtVP19eQ/YAUITT1K emOqiD56ktaq5Ze3/pdVjCTdrKgIhIsXZHrv2cIf2TO6QHV/tMY9BLd2Zx7bK7Sc5NvLbWeI= X-Google-Smtp-Source: ABdhPJxuORtcoywmiJHKGw7/e/sTlqjZr8hUhwhp69vsocE3Gg6CQXQi4OUVW+FGhouvJkN8KENzVDNOtUS5ng== X-Received: by 2002:adf:c404:: with SMTP id v4mr25721089wrf.85.1593609560649; Wed, 01 Jul 2020 06:19:20 -0700 (PDT) Date: Wed, 1 Jul 2020 14:19:07 +0100 In-Reply-To: <20200701131907.2665674-1-gprocida@google.com> Message-Id: <20200701131907.2665674-2-gprocida@google.com> Mime-Version: 1.0 References: <20200330091754.GH101337@google.com> <20200701131907.2665674-1-gprocida@google.com> X-Mailer: git-send-email 2.27.0.212.ge8ba1cc988-goog Subject: [PATCH v3 1/1] Fix has_net_changes for --leaf-changes-only mode To: libabigail@sourceware.org X-Spam-Status: No, score=-24.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" This function was not aware of --leaf-changes-only mode. - Stats counters for changed variables and types have different names in the different modes. - Net leaf type changes were not included in leaf mode. For some inputs, this resulted in abidiff producing an empty report but returning a non-zero exit status in --leaf-changes-only mode. For other inputs the combination of both issues still resulted in the correct return code. This included the following test-abidiff-exit test cases: - test-leaf-peeling - test-leaf2 - test-no-stray-comma This patch makes has_net_changes mirror emit_diff_stats, modulo flags like --non-reachable-types which if absent can still result in discrepancies between output and return code. The tests below verify that the exit code is zero when all the changes between the test files are suppressed. * src/abg-comparison.cc (corpus_diff::has_net_changes): Reorder the logic to match emit_diff_stats, add a note about this; in --leaf-changes-only mode use the right counters for function and variable changes and include type changes. * tests/data/Makefile.am: Add new test case files. * tests/data/test-abidiff-exit/test-net-change-report0.txt: Normal mode, nothing suppressed. * tests/data/test-abidiff-exit/test-net-change-report1.txt: Normal mode, everything suppressed. * tests/data/test-abidiff-exit/test-net-change-report2.txt: Leaf mode, nothing suppressed. * tests/data/test-abidiff-exit/test-net-change-report3.txt: Leaf mode, everything suppressions. * tests/data/test-abidiff-exit/test-net-change-v0.c: Test file * tests/data/test-abidiff-exit/test-net-change-v0.o: Test file * tests/data/test-abidiff-exit/test-net-change-v1.c: Test file * tests/data/test-abidiff-exit/test-net-change-v1.o: Test file * tests/data/test-abidiff-exit/test-net-change.abignore: This suppresses changes for all variables, functions and types in the test files, except for the 'victim' function. * tests/test-abidiff-exit.cc: Run new test cases. Reviewed-by: Matthias Maennich Signed-off-by: Giuliano Procida Reviewed-by: Matthias Maennich Signed-off-by: Giuliano Procida Signed-off-by: Dodji Seketeli --- src/abg-comparison.cc | 26 +++++++---- tests/data/Makefile.am | 9 ++++ .../test-net-change-report0.txt | 43 ++++++++++++++++++ .../test-net-change-report1.txt | 3 ++ .../test-net-change-report2.txt | 42 +++++++++++++++++ .../test-net-change-report3.txt | 5 ++ .../test-abidiff-exit/test-net-change-v0.c | 14 ++++++ .../test-abidiff-exit/test-net-change-v0.o | Bin 0 -> 3512 bytes .../test-abidiff-exit/test-net-change-v1.c | 14 ++++++ .../test-abidiff-exit/test-net-change-v1.o | Bin 0 -> 3552 bytes .../test-net-change.abignore | 8 ++++ tests/test-abidiff-exit.cc | 38 ++++++++++++++++ 12 files changed, 192 insertions(+), 10 deletions(-) create mode 100644 tests/data/test-abidiff-exit/test-net-change-report0.txt create mode 100644 tests/data/test-abidiff-exit/test-net-change-report1.txt create mode 100644 tests/data/test-abidiff-exit/test-net-change-report2.txt create mode 100644 tests/data/test-abidiff-exit/test-net-change-report3.txt create mode 100644 tests/data/test-abidiff-exit/test-net-change-v0.c create mode 100644 tests/data/test-abidiff-exit/test-net-change-v0.o create mode 100644 tests/data/test-abidiff-exit/test-net-change-v1.c create mode 100644 tests/data/test-abidiff-exit/test-net-change-v1.o create mode 100644 tests/data/test-abidiff-exit/test-net-change.abignore diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index c1d86a7f..e4b86426 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -10847,21 +10847,27 @@ corpus_diff::has_net_changes() const const diff_stats& stats = const_cast(this)-> apply_filters_and_suppressions_before_reporting(); + // Logic here should match emit_diff_stats. + // TODO: Possibly suppress things that won't be shown there. + bool leaf = context()->show_leaf_changes_only(); return (architecture_changed() || soname_changed() - || stats.net_num_func_changed() - || stats.net_num_vars_changed() - || stats.net_num_func_added() - || stats.net_num_added_func_syms() || stats.net_num_func_removed() - || stats.net_num_removed_func_syms() - || stats.net_num_vars_added() - || stats.net_num_added_var_syms() + || (leaf && stats.net_num_leaf_type_changes()) + || (leaf ? stats.net_num_leaf_func_changes() + : stats.net_num_func_changed()) + || stats.net_num_func_added() || stats.net_num_vars_removed() - || stats.net_num_removed_var_syms() - || stats.net_num_added_unreachable_types() + || (leaf ? stats.net_num_leaf_var_changes() + : stats.net_num_vars_changed()) + || stats.net_num_vars_added() || stats.net_num_removed_unreachable_types() - || stats.net_num_changed_unreachable_types()); + || stats.net_num_changed_unreachable_types() + || stats.net_num_added_unreachable_types() + || stats.net_num_removed_func_syms() + || stats.net_num_added_func_syms() + || stats.net_num_removed_var_syms() + || stats.net_num_added_var_syms()); } /// Apply the different filters that are registered to be applied to diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 8ccd50a0..539644b1 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -158,6 +158,15 @@ test-abidiff-exit/test-fun-param-v0.o \ test-abidiff-exit/test-fun-param-v1.abi \ test-abidiff-exit/test-fun-param-v1.c \ test-abidiff-exit/test-fun-param-v1.o \ +test-abidiff-exit/test-net-change.abignore \ +test-abidiff-exit/test-net-change-v0.c \ +test-abidiff-exit/test-net-change-v0.o \ +test-abidiff-exit/test-net-change-v1.c \ +test-abidiff-exit/test-net-change-v1.o \ +test-abidiff-exit/test-net-change-report0.txt \ +test-abidiff-exit/test-net-change-report1.txt \ +test-abidiff-exit/test-net-change-report2.txt \ +test-abidiff-exit/test-net-change-report3.txt \ \ test-diff-dwarf/test0-v0.cc \ test-diff-dwarf/test0-v0.o \ diff --git a/tests/data/test-abidiff-exit/test-net-change-report0.txt b/tests/data/test-abidiff-exit/test-net-change-report0.txt new file mode 100644 index 00000000..66712b01 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-net-change-report0.txt @@ -0,0 +1,43 @@ +Functions changes summary: 1 Removed, 2 Changed, 1 Added functions +Variables changes summary: 1 Removed, 1 Changed, 1 Added variables + +1 Removed function: + + [D] 'function int fun_removed()' {fun_removed} + +1 Added function: + + [A] 'function long int fun_added()' {fun_added} + +2 functions with some indirect sub-type change: + + [C] 'function int fun_changed()' has some indirect sub-type changes: + return type changed: + type name changed from 'int' to 'long int' + type size changed from 32 to 64 (in bits) + + [C] 'function void victim(type_changed*)' has some indirect sub-type changes: + parameter 1 of type 'type_changed*' has sub-type changes: + in pointed to type 'struct type_changed': + type size changed from 32 to 64 (in bits) + 1 data member change: + type of 'int type_changed::x' changed: + type name changed from 'int' to 'long int' + type size changed from 32 to 64 (in bits) + +1 Removed variable: + + [D] 'int var_removed' {var_removed} + +1 Added variable: + + [A] 'long int var_added' {var_added} + +1 Changed variable: + + [C] 'int var_changed' was changed to 'long int var_changed': + size of symbol changed from 4 to 8 + type of variable changed: + type name changed from 'int' to 'long int' + type size changed from 32 to 64 (in bits) + diff --git a/tests/data/test-abidiff-exit/test-net-change-report1.txt b/tests/data/test-abidiff-exit/test-net-change-report1.txt new file mode 100644 index 00000000..4dd60963 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-net-change-report1.txt @@ -0,0 +1,3 @@ +Functions changes summary: 0 Removed (1 filtered out), 0 Changed (2 filtered out), 0 Added (1 filtered out) functions +Variables changes summary: 0 Removed (1 filtered out), 0 Changed (1 filtered out), 0 Added (1 filtered out) variables + diff --git a/tests/data/test-abidiff-exit/test-net-change-report2.txt b/tests/data/test-abidiff-exit/test-net-change-report2.txt new file mode 100644 index 00000000..ca3b3e05 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-net-change-report2.txt @@ -0,0 +1,42 @@ +Leaf changes summary: 7 artifacts changed +Changed leaf types summary: 1 leaf type changed +Removed/Changed/Added functions summary: 1 Removed, 1 Changed, 1 Added function +Removed/Changed/Added variables summary: 1 Removed, 1 Changed, 1 Added variable + +1 Removed function: + + [D] 'function int fun_removed()' {fun_removed} + +1 Added function: + + [A] 'function long int fun_added()' {fun_added} + +1 function with some sub-type change: + + [C] 'function int fun_changed()' has some sub-type changes: + return type changed: + type name changed from 'int' to 'long int' + type size changed from 32 to 64 (in bits) + +1 Removed variable: + + [D] 'int var_removed' {var_removed} + +1 Added variable: + + [A] 'long int var_added' {var_added} + +1 Changed variable: + + [C] 'int var_changed' was changed to 'long int var_changed': + size of symbol changed from 4 to 8 + type of variable changed: + type name changed from 'int' to 'long int' + type size changed from 32 to 64 (in bits) + +'struct type_changed' changed: + type size changed from 32 to 64 (in bits) + there are data member changes: + type 'int' of 'type_changed::x' changed: + type name changed from 'int' to 'long int' + type size changed from 32 to 64 (in bits) diff --git a/tests/data/test-abidiff-exit/test-net-change-report3.txt b/tests/data/test-abidiff-exit/test-net-change-report3.txt new file mode 100644 index 00000000..4856a77a --- /dev/null +++ b/tests/data/test-abidiff-exit/test-net-change-report3.txt @@ -0,0 +1,5 @@ +Leaf changes summary: 0 artifact changed (3 filtered out) +Changed leaf types summary: 0 (1 filtered out) leaf type changed +Removed/Changed/Added functions summary: 0 Removed (1 filtered out), 0 Changed (1 filtered out), 0 Added function (1 filtered out) +Removed/Changed/Added variables summary: 0 Removed (1 filtered out), 0 Changed (1 filtered out), 0 Added variable (1 filtered out) + diff --git a/tests/data/test-abidiff-exit/test-net-change-v0.c b/tests/data/test-abidiff-exit/test-net-change-v0.c new file mode 100644 index 00000000..684b9c67 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-net-change-v0.c @@ -0,0 +1,14 @@ +int var_removed = 0; +int fun_removed() { return 0; } + +int var_changed = 0; +int fun_changed() { return 0; } + +struct type_removed { + int x; +}; +struct type_changed { + int x; +}; + +void victim(struct type_changed * dummy) { (void)dummy->x; } diff --git a/tests/data/test-abidiff-exit/test-net-change-v0.o b/tests/data/test-abidiff-exit/test-net-change-v0.o new file mode 100644 index 0000000000000000000000000000000000000000..bd2c744744880e83ba295ba16995c32a7438ec53 GIT binary patch literal 3512 zcmbtW&2Jk;6o2cD6Q^!mCoa$^MRE(M6uRp~R3%MGYY3zXA611^sS;G_+B>#a*t^ks z9h_DOwL(a}6$zXkcx0US6W;8ei@-kY5lPbM32;7OkM=J$T@&CHvR z^`~#WyPC5sV6osljCza$JSmLqx-{!hff=~6cIW3GsDJITVXoczF#{ z1)2Jww6*4#X6MMZto#b9Nt+$^SUw07NS$MbQ|2DC4ivVLo*#l$oS0UU$n8LV-?FT6^p6gs^Ijez%DR-5eFW3tqZf9;lwPZ ztslAf#w?L1@>*`nTsVZ8*U>ZS!YFFJvJ-`iIfXx2N6@wuF?|!TyCWZyQ0>KdZO0ejH71Ydo?fg<0$ZJ-Jsz$ zg0>fQYc!F5&G!;dnhxTA&}uni7$o2idcAGf^5Ttjnm#1kn_|?-S_Dmt*%vQesje)% zT0QH&;?7r{UNQ*9a$AHV4w~5Y;$~-gxOm1nbGquZt4_=7Z->oJ9EH)K?+n6^gV1*p zuhA8KISF1ZTwGaMs=oN9XaruECU+K3rUo3AWyBiacpt1`*_t~zQMijWKZ-d0NaV46 zy;S}@w=y-piUh>S_Zm4-_Va(3x-z@tq^E%WtD6OKkN@ zm_9qb$R>m|i!9_v+w(>NrIXJ0`&>wL_1T`=tq=qFrVJj}~)-@SJf&ip|2uWI~5$|mJ0oB0FP zzhU6K{#y#?`SX698_!t+mi z099qsp6L5hH*lWkbpz)*fZN~h;bVt7iBsKSD-pv4TzaIzZS?!##-i)FzGw{E8$sBL z&?jxL(TK&?F1Huc_holTHwXoX;1J+8qh3$ozXUgo65-;j?er6``H@N_IvcIn>j^dS z|EcCMo@&VT=X7;t9AiLf;_5B8cA?<%R_`%$(%o z_+Oc*w8=e%IOVJ>KdZ7T$oDFM&LQ!5KKLg^$}+ZQPI6pQ;5U*rYE15BbeR~j|5V`o zC{$V|m)?o2`9D&h6pp9)6J*ZcN6gHL5FA&RXM;MLm|XH_jsLqEpX)^9(|c=rh-->S^(*0zY+nCqv! QS@Dx; } diff --git a/tests/data/test-abidiff-exit/test-net-change-v1.o b/tests/data/test-abidiff-exit/test-net-change-v1.o new file mode 100644 index 0000000000000000000000000000000000000000..994ca58ecc5c35e7ecc51da87b685379c2734d6d GIT binary patch literal 3552 zcmbtW-D@0G6hE`mO*Y+Tn`EOV#KIImYO6DwV2NpJ+qKa&Q4uK=3mVedo!Q;N-I*{u z8#fgZr3%HD3W5qEh=M+ekNVsfAAIo5zd%vnL=eFTJ?GB3vo|-BClAa$=lsss{l4?& zGtaLV3S{Dg+r`hOdAhXs%5jXP?qGjF10!huoLW;Kh#!90eam`5nl*fLTVAp=o(89x&q#nv$XsZ3%k zwhXSM0g2yF?9fl_X2%WNzP-ETG(~K21}4%Xs8)*$&lZjA#o49e2_c*@C!FH!+XWMo z?FP*x=s|7Jk89ni>2_=FC~9~8S|{rHwf0UNH3QGBxuF+FfmiDW4Yv`r-Jn~e;{BTE zCaw@|#J!-^vi)I@fH&y%_F&hIx6`h9knHXFBPFln-6(8ZL70dz*YkW2uDo!~T3dR; zI_Es@ELwIi8HE0YwjcU&&_vaZo1F{8m1TSRtYxEoeE+mv6*GTxOo+f;gqp(Y`k;_=l_1h z=_3+b^r_0!yM?vMv2}DnjBHPm5$Q1dE2%lx&ZYwlOXGR|!NEaEul;L7EtSk3HED-T85T&a1+X~(F$fki`eQ;vG>pGs_7__&8uoaPlKgy}b=t2!yN9)AjL zbbj>s4#&v#mnqb+cjT+teMKtLcdH==W;wV%|x-Z=mdHw&DFEANT{U=E8zlWHf6Crq*56?C! z3hBON&#OPjh2%U@eYy|z`a6hGPT5Zs1---d^#@$mm;80~&Wpdr8|nn-lT5}*ev9L! zUGmTL4ao)>C;dJ~fiUi_gyAcWA7)4@$ni^<-iN&TTV%%#cBJ{E*ImZTdCjX$Ar>V? o`i479?;gE7dOWR3-cWz!OL!CQD(T~=ym|3MF7&w?jItj8AJ|S9SpWb4 literal 0 HcmV?d00001 diff --git a/tests/data/test-abidiff-exit/test-net-change.abignore b/tests/data/test-abidiff-exit/test-net-change.abignore new file mode 100644 index 00000000..6ba21189 --- /dev/null +++ b/tests/data/test-abidiff-exit/test-net-change.abignore @@ -0,0 +1,8 @@ +[suppress_function] + name_regexp = ^fun_ + +[suppress_variable] + name_regexp = ^var_ + +[suppress_type] + name_regexp = ^type_ diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc index 4d9c1943..c04b5835 100644 --- a/tests/test-abidiff-exit.cc +++ b/tests/test-abidiff-exit.cc @@ -212,6 +212,44 @@ InOutSpec in_out_specs[] = "data/test-abidiff-exit/test-fun-param-report.txt", "output/test-abidiff-exit/test-fun-param-report.txt" }, + { + "data/test-abidiff-exit/test-net-change-v0.o", + "data/test-abidiff-exit/test-net-change-v1.o", + "", + "--no-default-suppression --no-show-locs", + abigail::tools_utils::ABIDIFF_ABI_CHANGE + | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, + "data/test-abidiff-exit/test-net-change-report0.txt", + "output/test-abidiff-exit/test-net-change-report0.txt" + }, + { + "data/test-abidiff-exit/test-net-change-v0.o", + "data/test-abidiff-exit/test-net-change-v1.o", + "data/test-abidiff-exit/test-net-change.abignore", + "--no-default-suppression --no-show-locs", + abigail::tools_utils::ABIDIFF_OK, + "data/test-abidiff-exit/test-net-change-report1.txt", + "output/test-abidiff-exit/test-net-change-report1.txt" + }, + { + "data/test-abidiff-exit/test-net-change-v0.o", + "data/test-abidiff-exit/test-net-change-v1.o", + "", + "--no-default-suppression --no-show-locs --leaf-changes-only", + abigail::tools_utils::ABIDIFF_ABI_CHANGE + | abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE, + "data/test-abidiff-exit/test-net-change-report2.txt", + "output/test-abidiff-exit/test-net-change-report2.txt" + }, + { + "data/test-abidiff-exit/test-net-change-v0.o", + "data/test-abidiff-exit/test-net-change-v1.o", + "data/test-abidiff-exit/test-net-change.abignore", + "--no-default-suppression --no-show-locs --leaf-changes-only", + abigail::tools_utils::ABIDIFF_OK, + "data/test-abidiff-exit/test-net-change-report3.txt", + "output/test-abidiff-exit/test-net-change-report3.txt" + }, {0, 0, 0 ,0, abigail::tools_utils::ABIDIFF_OK, 0, 0} };