From patchwork Wed Oct 20 13:24:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 12572375 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81F61C433F5 for ; Wed, 20 Oct 2021 13:24:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D1D86136F for ; Wed, 20 Oct 2021 13:24:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230233AbhJTN1A (ORCPT ); Wed, 20 Oct 2021 09:27:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230217AbhJTN05 (ORCPT ); Wed, 20 Oct 2021 09:26:57 -0400 Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8ADD1C06161C for ; Wed, 20 Oct 2021 06:24:42 -0700 (PDT) Received: by mail-wm1-x333.google.com with SMTP id o24-20020a05600c511800b0030d9da600aeso10234844wms.4 for ; Wed, 20 Oct 2021 06:24:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=pUyDmkY2NIWpWT1V9EbM24O3P3os68Hb+UNSNCHOBXo=; b=bP69nHBiLyn7Bs4D/FkfJBsY9cEQtnkz0biSsMc3PTJDKWs13iSlJHh/TYSxxsTTLv lO6xZhxyC8KGVxaXnmxg7hmTjujtriM58+M1pFF4maKIGb28BfmY6aHHW+831LefQI8z AYd2ZjVxABzjVY8N3+rdScJlOoOtnG32e1qB5dB2ULR1m1VcpDdPMM8vdoSqCLbGBlFk xHdkL7z3pP5cYr89bseFpfv0LIT90Y1IMMgFjvy7/QRlY9bAV/B15AeWNX25NjX3FZrV S7ZWSagSsEM3uA4GVOt4TScbltaLq+WvOOWtoKSoFx9yGqcTCXox+ycHsL5/Ftgcq2Se H6xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pUyDmkY2NIWpWT1V9EbM24O3P3os68Hb+UNSNCHOBXo=; b=4raCYlaif84DX+zX1wgzMnZjJbvl7lnHGzCzTG4bdmzBbHrp3knpyTJKARhwfM5870 Zr7GgnHFrCMXH3Ms1tSVvGau8Sqm7ChC3kIHODAUt18cdkeVT2GwFVvj8jX1N/DDYJlx WPX67ZMpBuMUaaobMvZ7ifvV27WV5+uS3ij8xm4Z2u2d3We+2EQpfFhBcBxI/QGwNN8x LtF63M8XKs9BKcT/i3D7am4r1a5Q87nvRmQUypwe6rVyUxoJIzapSYpZc8jOftFJDwNZ 30VqmaGMhSysL7onvkpJmsGlkc/xxVPy3T8cWfs5Nyn+itTrH06a5xKeM1T0dgIkm0ir nosA== X-Gm-Message-State: AOAM5317WTVQBhqRpfF1dYnfKLqFa1Q64c1dreSh7CZW43GiShYZAAuv 76TcFlhQBHw76WS4Wg8gYtLJAZIHdwEf4Q== X-Google-Smtp-Source: ABdhPJxKlek0zYuRBON8AClgyabN54V/ZUI0NQVPrb+fvE5xW6NcMwx19K3J/KBzWDxqslo37OXMgA== X-Received: by 2002:a1c:4d15:: with SMTP id o21mr13772960wmh.167.1634736280687; Wed, 20 Oct 2021 06:24:40 -0700 (PDT) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id k17sm5933351wmj.0.2021.10.20.06.24.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 06:24:39 -0700 (PDT) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Junio C Hamano , Jeff King , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= Subject: [RFC PATCH v2 1/4] tag: use a "goto cleanup" pattern, leak less memory Date: Wed, 20 Oct 2021 15:24:33 +0200 Message-Id: X-Mailer: git-send-email 2.33.1.1338.g20da966911a In-Reply-To: References: <211020.864k9boo0f.gmgdl@evledraar.gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Change cmd_tag() to free its "struct string_list"'s instead of using an UNLEAK() pattern. This changes code added in 886e1084d78 (builtin/: add UNLEAKs, 2017-10-01). As shown in the context of the deceleration of the "struct msg_arg" (which I'm changing to use a designated initializer while at it, and to show the context in this change), that struct is just a thin wrapper around an int and "struct strbuf". Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/tag.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/builtin/tag.c b/builtin/tag.c index 6535ed27ee9..ad6c9855914 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -432,7 +432,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) int annotate = 0, force = 0; int cmdmode = 0, create_tag_object = 0; const char *msgfile = NULL, *keyid = NULL; - struct msg_arg msg = { 0, STRBUF_INIT }; + struct msg_arg msg = { .buf = STRBUF_INIT }; struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; struct ref_filter filter; @@ -482,6 +482,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")), OPT_END() }; + int ret = 0; setup_ref_filter_porcelain_msg(); @@ -529,7 +530,6 @@ int cmd_tag(int argc, const char **argv, const char *prefix) ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase); filter.ignore_case = icase; if (cmdmode == 'l') { - int ret; if (column_active(colopts)) { struct column_options copts; memset(&copts, 0, sizeof(copts)); @@ -540,7 +540,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) ret = list_tags(&filter, sorting, &format); if (column_active(colopts)) stop_column_filter(); - return ret; + goto cleanup; } if (filter.lines != -1) die(_("-n option is only allowed in list mode")); @@ -552,12 +552,15 @@ int cmd_tag(int argc, const char **argv, const char *prefix) die(_("--points-at option is only allowed in list mode")); if (filter.reachable_from || filter.unreachable_from) die(_("--merged and --no-merged options are only allowed in list mode")); - if (cmdmode == 'd') - return delete_tags(argv); + if (cmdmode == 'd') { + ret = delete_tags(argv); + goto cleanup; + } if (cmdmode == 'v') { if (format.format && verify_ref_format(&format)) usage_with_options(git_tag_usage, options); - return for_each_tag_name(argv, verify_tag, &format); + ret = for_each_tag_name(argv, verify_tag, &format); + goto cleanup; } if (msg.given || msgfile) { @@ -626,10 +629,11 @@ int cmd_tag(int argc, const char **argv, const char *prefix) printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(&prev, DEFAULT_ABBREV)); - UNLEAK(buf); - UNLEAK(ref); - UNLEAK(reflog_msg); - UNLEAK(msg); - UNLEAK(err); - return 0; +cleanup: + strbuf_release(&buf); + strbuf_release(&ref); + strbuf_release(&reflog_msg); + strbuf_release(&msg.buf); + strbuf_release(&err); + return ret; } From patchwork Wed Oct 20 13:24:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 12572377 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C890DC433F5 for ; Wed, 20 Oct 2021 13:24:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B41066134F for ; Wed, 20 Oct 2021 13:24:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230232AbhJTN1D (ORCPT ); Wed, 20 Oct 2021 09:27:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230260AbhJTN07 (ORCPT ); Wed, 20 Oct 2021 09:26:59 -0400 Received: from mail-wm1-x32d.google.com (mail-wm1-x32d.google.com [IPv6:2a00:1450:4864:20::32d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02026C061753 for ; Wed, 20 Oct 2021 06:24:44 -0700 (PDT) Received: by mail-wm1-x32d.google.com with SMTP id b189-20020a1c1bc6000000b0030da052dd4fso10241327wmb.3 for ; Wed, 20 Oct 2021 06:24:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FOrypeBWeRFbhhIaVzych6YWS0VZktygxcW2Snudt+c=; b=JU+dg2ikAqBAH+S0IrnY+wUIevL7MXFLf6b3wkfnO1IzUDVzfDgjqsy+3qJEsoPdGz Qjow+Suz+f4e92CTbfuPtFQJOURHHiqN0NaR/6cKtKvae2No1/OOjF4g3PzKus6FTqGG hLYXIeFwvDoQqI5i7zCI0U0kNut37ihjSYQZcYoomxx+YDpR7y+wiSdP7ObArrbiGe5b VS5eBj7lyJGFftpfGaz8hgbhQqbd3Uiu9Nd6gXgvQbMgsamR9fZNQq6810UQEHXcre4p k1ZhV8Sf0H3C2GkckE0lkGrrJztFNJ2X4qaf1AZT95jLKGwzRLzPeHvqBQBl/BbtxBj5 yysQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FOrypeBWeRFbhhIaVzych6YWS0VZktygxcW2Snudt+c=; b=kh52bQbS4NpMxGUWLDkbF2YHgur7yYYrleug/gzgeVwBaB9ODPUoJNZBtfRPu4wy5Q Vcp5PIO6R1Y5jrBXehhh0dgZdNy1cSBc52YgM+R3eqb9d2PPtWFzy6dHmu6GX4WQ/tA6 /s4A2x7YVk/FIJ3OTsA7Yf2ILKhdE3EzCbFqNzgU39QmR5ZoOHnX8ad+DSfScX/IL5Rg ttLsxZIRvsh0cbws37LQrgEm0zAsfyxj6mDZG8gzg5cP3cu+K8JWYf0nEwrOTbGi0E3z aly7Q+tR1miamjzVTnaekf3j0721URDf4buETbkIiM8zITCrhcZ8ueYL+s41x4/eVp0Q bqUA== X-Gm-Message-State: AOAM532GI+7V5t1FJSzBc85lZUagA0r58dCX8p9O5qxa+AEogx8aD1yC 4CR4n8rp6Qul+6bjtTBlBaglxG0Fte7HTQ== X-Google-Smtp-Source: ABdhPJxExCiR3DBDn22kPZX+rSGVCIwuWrMpB4UqF32L6WT4XXMlIbTqHnggRr24U5H4DGC5Oh327Q== X-Received: by 2002:a05:600c:3b11:: with SMTP id m17mr14039755wms.157.1634736283286; Wed, 20 Oct 2021 06:24:43 -0700 (PDT) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id k17sm5933351wmj.0.2021.10.20.06.24.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 06:24:40 -0700 (PDT) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Junio C Hamano , Jeff King , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= Subject: [RFC PATCH v2 2/4] ref-filter API user: add and use a ref_sorting_release() Date: Wed, 20 Oct 2021 15:24:34 +0200 Message-Id: X-Mailer: git-send-email 2.33.1.1338.g20da966911a In-Reply-To: References: <211020.864k9boo0f.gmgdl@evledraar.gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Add a ref_sorting_release() and use it for some of the current API users, the ref_sorting_default() function and its siblings will do a malloc() which wasn't being free'd previously. Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/for-each-ref.c | 2 +- builtin/tag.c | 1 + ref-filter.c | 8 ++++++++ ref-filter.h | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 642b4b888fb..16a2c7d57ca 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -96,6 +96,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) ref_array_clear(&array); free_commit_list(filter.with_commit); free_commit_list(filter.no_commit); - UNLEAK(sorting); + ref_sorting_release(sorting); return 0; } diff --git a/builtin/tag.c b/builtin/tag.c index ad6c9855914..6fe646710d6 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -630,6 +630,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) find_unique_abbrev(&prev, DEFAULT_ABBREV)); cleanup: + ref_sorting_release(sorting); strbuf_release(&buf); strbuf_release(&ref); strbuf_release(&reflog_msg); diff --git a/ref-filter.c b/ref-filter.c index add429be797..bdf8b0725df 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2705,6 +2705,14 @@ int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset) return 0; } +void ref_sorting_release(struct ref_sorting *sorting) +{ + struct ref_sorting *next = sorting->next; + if (next) + ref_sorting_release(next); + free(sorting); +} + int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset) { struct ref_filter *rf = opt->value; diff --git a/ref-filter.h b/ref-filter.h index b636f4389d0..6228458d306 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -127,6 +127,8 @@ void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *atom); int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset); /* Default sort option based on refname */ struct ref_sorting *ref_default_sorting(void); +/* Release a "struct ref_sorting" */ +void ref_sorting_release(struct ref_sorting *); /* Function to parse --merged and --no-merged options */ int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset); /* Get the current HEAD's description */ From patchwork Wed Oct 20 13:24:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 12572379 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 928B9C433EF for ; Wed, 20 Oct 2021 13:24:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7B037610A2 for ; Wed, 20 Oct 2021 13:24:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230231AbhJTN1E (ORCPT ); Wed, 20 Oct 2021 09:27:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230261AbhJTN1A (ORCPT ); Wed, 20 Oct 2021 09:27:00 -0400 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 24E40C06161C for ; Wed, 20 Oct 2021 06:24:46 -0700 (PDT) Received: by mail-wm1-x329.google.com with SMTP id g39so14850034wmp.3 for ; Wed, 20 Oct 2021 06:24:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OgSAgl5f34N+81acmtEqcKf6kye+twP0/+MtnJHP0Q4=; b=fD9gqJK5DMJTCGn+2vJ4fl4ozKlKjZWu8rHoIxB2aRkgeammJw221w2mL13ihkkklf z7G695wME1/U7D8i0pX06bGigKAfAz7FxOFAUuAmf0bHit/dZoAGaPiepNDosr9a6gd0 Qp52fPlkqlfSlbdYxaB+9OQj2ZnLDbu+mfhxvWoZL2rpG4Z6FNEU5Ujnmt/Iq8QwBSRW NbUXhRJH+Z1nP+Rv6jFc8iPYuYMp1o0Xg5+WhhTA80tW32/W2NbizO+ukFOoPQirCoF7 Nxjzk+g3L0CZ5+QiP5vx0C9WAkdUG8B1YhOggt7Ibp2DacnrAWxSIwXL+D5o1BpD2hxb hcwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OgSAgl5f34N+81acmtEqcKf6kye+twP0/+MtnJHP0Q4=; b=QbH0WZB55mGCcUzLPgXEqrO3OsSnzu7LunBAJN9Q4SMucBWFYNqUkorPEN2NoepcHd 6A7vRVFH5WIPdiOV31la7HgWL/N23kbJqkdJouQ/8pshAL2EGoXv29vvFWB38NNGC7yY XxGUYIceLkBg9CMvCPyMKVJeBG6zVDACN84dtd2o4lx1n2NZ5ta4NxvAlFETtVBgNmRH R830Kt1nxdMW0NpKTS/yhH8DvZicR+jNQNQHKniMzrOc9OsZd31sjdiZiqyiCyGOZUDn YurhV8ZV0Q57mNa6y+tp79Kll5raRunhmWctgbi9v+sKPpOIESzwH3ShyWgIsnzPCVMm LNpg== X-Gm-Message-State: AOAM530mdhOl+3wwyjFNRUmu8cyO0VLkNKfyYfJHFcy+CDsdej/6Vnq6 oVqiAvYvA5N/3RNS6iIxtFOc3VAN4dQYqA== X-Google-Smtp-Source: ABdhPJx+VdVuGansaLevvqeNq2SSYIhpidB5Ez5Ds4umcVUS4GAqaNwL3rqtVKzWt3jk5DrWbepFJw== X-Received: by 2002:adf:e746:: with SMTP id c6mr51484818wrn.367.1634736284236; Wed, 20 Oct 2021 06:24:44 -0700 (PDT) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id k17sm5933351wmj.0.2021.10.20.06.24.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 06:24:43 -0700 (PDT) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Junio C Hamano , Jeff King Subject: [RFC PATCH v2 3/4] for-each-ref: delay parsing of --sort= options Date: Wed, 20 Oct 2021 15:24:35 +0200 Message-Id: X-Mailer: git-send-email 2.33.1.1338.g20da966911a In-Reply-To: References: <211020.864k9boo0f.gmgdl@evledraar.gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Junio C Hamano The for-each-ref family of commands invoke parsers immediately when it sees each --sort= option, and die before even seeing the other options on the command line when the is unrecognised. Instead, accumulate them in a string list, and have them parsed into a ref_sorting structure after the command line parsing is done. As a consequence, "git branch --sort=bogus -h" used to fail to give the brief help, which arguably may have been a feature, now does so, which is more consistent with how other options work. The patch is smaller than the actual extent of the "damage" to the codebase, thanks to the fact that the original code consistently used OPT_REF_SORT() macro to handle command line options. We only needed to replace the variable used for the list, and implementation of the callback function used in the macro. The old rule was for the users of the API to: - Declare ref_sorting and ref_sorting_tail variables; - OPT_REF_SORT() macro will instantiate ref_sorting instance (which may barf and die) and append it to the tail; - Append to the tail each ref_sorting read from the configuration by parsing in the config callback (which may barf and die); - See if ref_sorting is null and use ref_sorting_default() instead. Now the rule is not all that different but is simpler: - Declare ref_sorting_options string list. - OPT_REF_SORT() macro will append it to the string list; - Append to the string list the sort key read from the configuration; - call ref_sorting_options() to turn the string list to ref_sorting structure (which also deals with the default value). As side effects, this change also cleans up a few issues: - 95be717c (parse_opt_ref_sorting: always use with NONEG flag, 2019-03-20) muses that "git for-each-ref --no-sort" should simply clear the sort keys accumulated so far; it now does. - The implementation detail of "struct ref_sorting" and the helper function parse_ref_sorting() can now be private to the ref-filter API implementation. - If you set branch.sort to a bogus value, the any "git branch" invocation, not only the listing mode, would abort with the original code; now it doesn't Signed-off-by: Junio C Hamano --- builtin/branch.c | 13 ++++++------- builtin/for-each-ref.c | 8 ++++---- builtin/ls-remote.c | 13 ++++++++----- builtin/tag.c | 13 ++++++------- ref-filter.c | 34 ++++++++++++++++++++++++---------- ref-filter.h | 28 ++++++++++------------------ t/t3200-branch.sh | 12 +++++++++++- t/t6300-for-each-ref.sh | 5 +++++ 8 files changed, 74 insertions(+), 52 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 0b7ed82654a..69211f8dd1c 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -77,12 +77,11 @@ define_list_config_array(color_branch_slots); static int git_branch_config(const char *var, const char *value, void *cb) { const char *slot_name; - struct ref_sorting **sorting_tail = (struct ref_sorting **)cb; if (!strcmp(var, "branch.sort")) { if (!value) return config_error_nonbool(var); - parse_ref_sorting(sorting_tail, value); + string_list_append(cb, value); return 0; } @@ -624,7 +623,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix) enum branch_track track; struct ref_filter filter; int icase = 0; - static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting; + static struct ref_sorting *sorting; + struct string_list sorting_options = STRING_LIST_INIT_DUP; struct ref_format format = REF_FORMAT_INIT; struct option options[] = { @@ -665,7 +665,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) OPT_MERGED(&filter, N_("print only branches that are merged")), OPT_NO_MERGED(&filter, N_("print only branches that are not merged")), OPT_COLUMN(0, "column", &colopts, N_("list branches in columns")), - OPT_REF_SORT(sorting_tail), + OPT_REF_SORT(&sorting_options), OPT_CALLBACK(0, "points-at", &filter.points_at, N_("object"), N_("print only branches of the object"), parse_opt_object_name), OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")), @@ -682,7 +682,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(builtin_branch_usage, options); - git_config(git_branch_config, sorting_tail); + git_config(git_branch_config, &sorting_options); track = git_branch_track; @@ -748,8 +748,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) * local branches 'refs/heads/...' and finally remote-tracking * branches 'refs/remotes/...'. */ - if (!sorting) - sorting = ref_default_sorting(); + sorting = ref_sorting_options(&sorting_options); ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase); ref_sorting_set_sort_flags_all( sorting, REF_SORTING_DETACHED_HEAD_FIRST, 1); diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 16a2c7d57ca..6f62f40d126 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -17,7 +17,8 @@ static char const * const for_each_ref_usage[] = { int cmd_for_each_ref(int argc, const char **argv, const char *prefix) { int i; - struct ref_sorting *sorting = NULL, **sorting_tail = &sorting; + struct ref_sorting *sorting; + struct string_list sorting_options = STRING_LIST_INIT_DUP; int maxcount = 0, icase = 0; struct ref_array array; struct ref_filter filter; @@ -39,7 +40,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) OPT_INTEGER( 0 , "count", &maxcount, N_("show only matched refs")), OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")), OPT__COLOR(&format.use_color, N_("respect format colors")), - OPT_REF_SORT(sorting_tail), + OPT_REF_SORT(&sorting_options), OPT_CALLBACK(0, "points-at", &filter.points_at, N_("object"), N_("print only refs which points at the given object"), parse_opt_object_name), @@ -70,8 +71,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) if (verify_ref_format(&format)) usage_with_options(for_each_ref_usage, opts); - if (!sorting) - sorting = ref_default_sorting(); + sorting = ref_sorting_options(&sorting_options); ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase); filter.ignore_case = icase; diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index 318949c3d75..44448fa61d1 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -54,7 +54,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) struct transport *transport; const struct ref *ref; struct ref_array ref_array; - static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting; + struct string_list sorting_options = STRING_LIST_INIT_DUP; struct option options[] = { OPT__QUIET(&quiet, N_("do not print remote URL")), @@ -68,7 +68,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL), OPT_BOOL(0, "get-url", &get_url, N_("take url..insteadOf into account")), - OPT_REF_SORT(sorting_tail), + OPT_REF_SORT(&sorting_options), OPT_SET_INT_F(0, "exit-code", &status, N_("exit with exit code 2 if no matching refs are found"), 2, PARSE_OPT_NOCOMPLETE), @@ -86,8 +86,6 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) packet_trace_identity("ls-remote"); - UNLEAK(sorting); - if (argc > 1) { int i; CALLOC_ARRAY(pattern, argc); @@ -139,8 +137,13 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) item->symref = xstrdup_or_null(ref->symref); } - if (sorting) + if (sorting_options.nr) { + struct ref_sorting *sorting; + + sorting = ref_sorting_options(&sorting_options); ref_array_sort(sorting, &ref_array); + ref_sorting_release(sorting); + } for (i = 0; i < ref_array.nr; i++) { const struct ref_array_item *ref = ref_array.items[i]; diff --git a/builtin/tag.c b/builtin/tag.c index 6fe646710d6..41863c5ab77 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -178,7 +178,6 @@ static const char tag_template_nocleanup[] = static int git_tag_config(const char *var, const char *value, void *cb) { int status; - struct ref_sorting **sorting_tail = (struct ref_sorting **)cb; if (!strcmp(var, "tag.gpgsign")) { config_sign_tag = git_config_bool(var, value); @@ -188,7 +187,7 @@ static int git_tag_config(const char *var, const char *value, void *cb) if (!strcmp(var, "tag.sort")) { if (!value) return config_error_nonbool(var); - parse_ref_sorting(sorting_tail, value); + string_list_append(cb, value); return 0; } @@ -436,7 +435,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix) struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; struct ref_filter filter; - static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting; + struct ref_sorting *sorting; + struct string_list sorting_options = STRING_LIST_INIT_DUP; struct ref_format format = REF_FORMAT_INIT; int icase = 0; int edit_flag = 0; @@ -470,7 +470,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_WITHOUT(&filter.no_commit, N_("print only tags that don't contain the commit")), OPT_MERGED(&filter, N_("print only tags that are merged")), OPT_NO_MERGED(&filter, N_("print only tags that are not merged")), - OPT_REF_SORT(sorting_tail), + OPT_REF_SORT(&sorting_options), { OPTION_CALLBACK, 0, "points-at", &filter.points_at, N_("object"), N_("print only tags of the object"), PARSE_OPT_LASTARG_DEFAULT, @@ -486,7 +486,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) setup_ref_filter_porcelain_msg(); - git_config(git_tag_config, sorting_tail); + git_config(git_tag_config, &sorting_options); memset(&opt, 0, sizeof(opt)); memset(&filter, 0, sizeof(filter)); @@ -525,8 +525,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) die(_("--column and -n are incompatible")); colopts = 0; } - if (!sorting) - sorting = ref_default_sorting(); + sorting = ref_sorting_options(&sorting_options); ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase); filter.ignore_case = icase; if (cmdmode == 'l') { diff --git a/ref-filter.c b/ref-filter.c index bdf8b0725df..ec7f30c5d31 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2470,6 +2470,12 @@ static int memcasecmp(const void *vs1, const void *vs2, size_t n) return 0; } +struct ref_sorting { + struct ref_sorting *next; + int atom; /* index into used_atom array (internal) */ + enum ref_sorting_order sort_flags; +}; + static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, struct ref_array_item *b) { struct atom_value *va, *vb; @@ -2663,7 +2669,7 @@ static int parse_sorting_atom(const char *atom) } /* If no sorting option is given, use refname to sort as default */ -struct ref_sorting *ref_default_sorting(void) +static struct ref_sorting *ref_default_sorting(void) { static const char cstr_name[] = "refname"; @@ -2674,7 +2680,7 @@ struct ref_sorting *ref_default_sorting(void) return sorting; } -void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg) +static void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg) { struct ref_sorting *s; @@ -2692,17 +2698,25 @@ void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg) s->atom = parse_sorting_atom(arg); } -int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset) +struct ref_sorting *ref_sorting_options(struct string_list *options) { + struct string_list_item *item; + struct ref_sorting *sorting = NULL, **tail = &sorting; + + if (!options->nr) { + sorting = ref_default_sorting(); + } else { + for_each_string_list_item(item, options) + parse_ref_sorting(tail, item->string); + } + /* - * NEEDSWORK: We should probably clear the list in this case, but we've - * already munged the global used_atoms list, which would need to be - * undone. + * From here on, the ref_sorting list should be used to talk + * about the sort order used for the output. The caller + * should not touch the string form anymore. */ - BUG_ON_OPT_NEG(unset); - - parse_ref_sorting(opt->value, arg); - return 0; + string_list_clear(options, 0); + return sorting; } void ref_sorting_release(struct ref_sorting *sorting) diff --git a/ref-filter.h b/ref-filter.h index 6228458d306..b6a317e92c5 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -23,16 +23,13 @@ #define FILTER_REFS_KIND_MASK (FILTER_REFS_ALL | FILTER_REFS_DETACHED_HEAD) struct atom_value; +struct ref_sorting; -struct ref_sorting { - struct ref_sorting *next; - int atom; /* index into used_atom array (internal) */ - enum { - REF_SORTING_REVERSE = 1<<0, - REF_SORTING_ICASE = 1<<1, - REF_SORTING_VERSION = 1<<2, - REF_SORTING_DETACHED_HEAD_FIRST = 1<<3, - } sort_flags; +enum ref_sorting_order { + REF_SORTING_REVERSE = 1<<0, + REF_SORTING_ICASE = 1<<1, + REF_SORTING_VERSION = 1<<2, + REF_SORTING_DETACHED_HEAD_FIRST = 1<<3, }; struct ref_array_item { @@ -97,9 +94,8 @@ struct ref_format { #define OPT_NO_MERGED(f, h) _OPT_MERGED_NO_MERGED("no-merged", f, h) #define OPT_REF_SORT(var) \ - OPT_CALLBACK_F(0, "sort", (var), \ - N_("key"), N_("field name to sort on"), \ - PARSE_OPT_NONEG, parse_opt_ref_sorting) + OPT_STRING_LIST(0, "sort", (var), \ + N_("key"), N_("field name to sort on")) /* * API for filtering a set of refs. Based on the type of refs the user @@ -121,12 +117,8 @@ int format_ref_array_item(struct ref_array_item *info, struct ref_format *format, struct strbuf *final_buf, struct strbuf *error_buf); -/* Parse a single sort specifier and add it to the list */ -void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *atom); -/* Callback function for parsing the sort option */ -int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset); -/* Default sort option based on refname */ -struct ref_sorting *ref_default_sorting(void); +/* Convert list of sort options into ref_sorting */ +struct ref_sorting *ref_sorting_options(struct string_list *); /* Release a "struct ref_sorting" */ void ref_sorting_release(struct ref_sorting *); /* Function to parse --merged and --no-merged options */ diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index e575ffb4ffb..0e23d18807b 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -1418,7 +1418,17 @@ test_expect_success 'invalid sort parameter in configuration' ' ( cd sort && git config branch.sort "v:notvalid" && - test_must_fail git branch + + # this works in the "listing" mode, so bad sort key + # is a dying offence. + test_must_fail git branch && + + # these do not need to use sorting, and should all + # succeed + git branch newone main && + git branch -c newone newerone && + git branch -m newone newestone && + git branch -d newerone newestone ) ' diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 80679d5e12d..83921502a40 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -419,6 +419,11 @@ test_expect_success 'Verify descending sort' ' test_cmp expected actual ' +test_expect_success 'Give help even with invalid sort atoms' ' + test_expect_code 129 git for-each-ref --sort=bogus -h >actual 2>&1 && + grep "^usage: git for-each-ref" actual +' + cat >expected <<\EOF refs/tags/testtag refs/tags/testtag-2 From patchwork Wed Oct 20 13:24:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= X-Patchwork-Id: 12572381 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A5FDDC433F5 for ; Wed, 20 Oct 2021 13:24:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8D14761260 for ; Wed, 20 Oct 2021 13:24:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230260AbhJTN1E (ORCPT ); Wed, 20 Oct 2021 09:27:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36414 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230234AbhJTN1B (ORCPT ); Wed, 20 Oct 2021 09:27:01 -0400 Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E2BDC061760 for ; Wed, 20 Oct 2021 06:24:47 -0700 (PDT) Received: by mail-wm1-x334.google.com with SMTP id 67-20020a1c1946000000b0030d4c90fa87so10235919wmz.2 for ; Wed, 20 Oct 2021 06:24:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=G6BeScdJhcr25sX0/w49pGmBdQVB2zcAGqQuKdD7s6U=; b=b8U6QvOzBhdyqAwoMfvm8VSNvh6flYFfHujtkHx9oLKe7/ihHfRooJDsiECP61vCQg LUI5Jqvsb0BD44G5S2OkHbdQtUIg0g8DFfCGULBi8HM0+YZnJ/2LVTwaZQt4lte9wEcY TyjIobLvjj+zmnEL94/mhvwA7YhZEIFvzL7d8ucF9PRTkB8KGLk4CU9z7C0LYo8NQ/Ac 2+ypnGkYBuAeaDrSTuR69XdNL4bfFMV1j+Q3O2kXMnPCRGShEkMD8ucKJCntVE6eHsHb c7f+rCy0LCci8mD146xqQeuUueZTzCzwN13ZedfOF709qw6XDjPBBZsPvvlkL+xpQSvn 6E4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=G6BeScdJhcr25sX0/w49pGmBdQVB2zcAGqQuKdD7s6U=; b=bvgHJaw6/VkDfJ2g5IQ0yJHvIjy6xCZJcGEMwkE0ru0m6Au1AvF52z9U6SnYwLqDbL nDXHeY+h9XsSf0fV7h6w/WpggPQ99EUAkNoDbNsdPOe2RGzBpFmCRfez1yNL+GviX8dN jqRE2hOUrbmO11vJCFQcY+GiCdOSLrKL2oWaRo32VY2lV7dgb+Z2XOT0Ennsfb+o0Boo uSJfTWXeSlZMFlu3UJyEWzpv1SQlYUB1HdT0FhYAQmGFnGfytVKPzNFQXVVcUYKQjdGL op10gwaYtmxXd/gO/6XYxqbsaEv0Cwj7M5Em4P25Cgkh5rNMSrhykMhTV9G+1fOgIE9O zusw== X-Gm-Message-State: AOAM530yO6vypzjHMc+L3hE1ft17l5iAAQqnOAYiCxWYo406qx9c3al2 twz81mYOzsMyuI8U5X/SqxFg45mizpTRZQ== X-Google-Smtp-Source: ABdhPJy2MMnrNFy6GBMptME/r0JALFwH3XjyM6kY/3QXWa6ukdLW4ERmGJOu60v8qS64HjgaaBHY7w== X-Received: by 2002:adf:f190:: with SMTP id h16mr40492248wro.250.1634736285380; Wed, 20 Oct 2021 06:24:45 -0700 (PDT) Received: from vm.nix.is (vm.nix.is. [2a01:4f8:120:2468::2]) by smtp.gmail.com with ESMTPSA id k17sm5933351wmj.0.2021.10.20.06.24.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Oct 2021 06:24:44 -0700 (PDT) From: =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= To: git@vger.kernel.org Cc: Junio C Hamano , Jeff King , =?utf-8?b?w4Z2YXIgQXJuZmrDtnLDsCBCamFybWFzb24=?= Subject: [RFC PATCH v2 4/4] branch: use ref_sorting_release() Date: Wed, 20 Oct 2021 15:24:36 +0200 Message-Id: X-Mailer: git-send-email 2.33.1.1338.g20da966911a In-Reply-To: References: <211020.864k9boo0f.gmgdl@evledraar.gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Use a ref_sorting_release() in branch.c to free the memory from the ref_sorting_options(). This plugs the final in-tree memory leak of that API. In the preceding commit the "sorting" variable was left in the cmd_branch() scope, even though that wasn't needed anymore. Move it to the "else if (list)" scope instead. We can also move the "struct string_list" only used for that branch to be declared in that block That "struct ref_sorting" does not need to be "static" (and isn't re-used). The "ref_sorting_options()" will return a valid one, we don't need to make it "static" to have it zero'd out. That it was static was another artifact of the pre-image of the preceding commit. Signed-off-by: Ævar Arnfjörð Bjarmason --- builtin/branch.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 69211f8dd1c..3963c592f56 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -69,7 +69,6 @@ static const char *color_branch_slots[] = { [BRANCH_COLOR_WORKTREE] = "worktree", }; -static struct string_list output = STRING_LIST_INIT_DUP; static unsigned int colopts; define_list_config_array(color_branch_slots); @@ -406,7 +405,8 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r return strbuf_detach(&fmt, NULL); } -static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting, struct ref_format *format) +static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting, + struct ref_format *format, struct string_list *output) { int i; struct ref_array array; @@ -448,7 +448,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin if (column_active(colopts)) { assert(!filter->verbose && "--column and --verbose are incompatible"); /* format to a string_list to let print_columns() do its job */ - string_list_append(&output, out.buf); + string_list_append(output, out.buf); } else { fwrite(out.buf, 1, out.len, stdout); putchar('\n'); @@ -623,7 +623,6 @@ int cmd_branch(int argc, const char **argv, const char *prefix) enum branch_track track; struct ref_filter filter; int icase = 0; - static struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; struct ref_format format = REF_FORMAT_INIT; @@ -737,6 +736,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix) print_current_branch_name(); return 0; } else if (list) { + struct ref_sorting *sorting; + static struct string_list output = STRING_LIST_INIT_DUP; + /* git branch --list also shows HEAD when it is detached */ if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached) filter.kind |= FILTER_REFS_DETACHED_HEAD; @@ -752,9 +754,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix) ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase); ref_sorting_set_sort_flags_all( sorting, REF_SORTING_DETACHED_HEAD_FIRST, 1); - print_ref_list(&filter, sorting, &format); + print_ref_list(&filter, sorting, &format, &output); print_columns(&output, colopts, NULL); string_list_clear(&output, 0); + ref_sorting_release(sorting); return 0; } else if (edit_description) { const char *branch_name;