From patchwork Sat Jun 17 20:40:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13283717 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19BDEEB64D9 for ; Sat, 17 Jun 2023 20:41:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346524AbjFQUlN (ORCPT ); Sat, 17 Jun 2023 16:41:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237981AbjFQUlB (ORCPT ); Sat, 17 Jun 2023 16:41:01 -0400 Received: from mout.web.de (mout.web.de [212.227.15.14]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E7138E72 for ; Sat, 17 Jun 2023 13:40:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=s29768273; t=1687034458; x=1687639258; i=l.s.r@web.de; bh=4SEIxANFbIRdpqzIEcjzwrNp/gRTrpOzbQO0LvGX18k=; h=X-UI-Sender-Class:Date:Subject:From:To:References:In-Reply-To; b=tpdDqnO23gV8OWS/QmNY0CdGSaYKulT/OIlBXe1KQWdCUS0W3qm8rfn3o4NIu3UMLuwCngA uQfdbmGHzt2+1rxLvdf40qy8ikC8x3ICBjw+4v1TJdM+3tEGLkuwEZiJIYu6lRkkMz0snvn4q U5TyDlV/h7JelSlQ/iK/Z7EraZsBAufrZbLFPkpuw4Y/Xbu0Nf+nvttnKXdpnZ/k31ranyusU aA+chXO2CGKtgiYZqgJ4a+HFI7w6z1NhrMDM2MGaSGGOi5ac4CuzUqdLuwXfNTi1RNfXZwMt9 djYnHwd0bm3vgs8nBXboXIU8atPbJEVC37EisscS10q9V2bIDiTw== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([91.47.157.195]) by smtp.web.de (mrweb005 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MXoYS-1qcCfO0l36-00YUcl for ; Sat, 17 Jun 2023 22:40:58 +0200 Message-ID: <9aee9e14-5459-b62b-6427-23fc0d532b5b@web.de> Date: Sat, 17 Jun 2023 22:40:57 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 Subject: [PATCH 1/5] pretty: factor out expand_separator() Content-Language: en-US From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List References: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> In-Reply-To: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> X-Provags-ID: V03:K1:WIgyYq1xza4audC/CpVKCa8bF0dEMhe2Kjo/OAmCNQ9n32eGMC6 jALdzyCphD0MKHjhUrE8g6u8Lniqj06FIcXzwBJIlseiANEYPf9sWY0cjYfbg1XQSyAoj6c SajHf7PQpBS3TF4FMCro/0bw1L0S+aYEMkw9r0zHbKaztXYSgVmg1W/tTcH2CxmGAWpu7FZ MnX1l0BBvR0whIYjAnBwA== UI-OutboundReport: notjunk:1;M01:P0:4pbQ8EREbBo=;NTTQ/XmJhQELOv4ab6eVNmnaENa kOO2TfIpBoXV4i/ORFM+snwdfJJGuRH+fs+HQP8zQyUldfb/d+U/iovdAHC+hlSY7HN6gVnrb f6nhTgiz3a1Cp/B7/PHX4ryuVfOT2TD1dKkFpvOW0W8lPmroHWyPBjH6hxkAstDcpB/vVKW5B YGyoWNvL/jbO7HqMmpzXhVSduV4w5YIRx7rm3aXMXsZkxzbj/VbEyNLNS3PSaBeWoSgRKgJQ3 n424OyttInlggD+tUHzzBklCFIReIoOFkwbedwhMtUNHgF11Kb3dt4Dq7sWlcnyb1lF3moKyS L151p4wOWUbe0cX5fR1Ydi5TIrzVtWA3R3zCD2XsN2Svv6yUz0H0/fQNvU4zscb4cQ7OF9ij6 NT1QwOU2674I020PzFGZO2bRAloFq880sbEtwuDL/5Is9c7nwKS/Jut2WzOPapfHWm7eXnXdS sFn2MHArMElzPMaXlqPMEU+r7m4Lm2Diqhrk+Bi0AjUwPihICyaP9lzyv9/X426DgOQkwYhmx JoCZgvfeQlXuRrKYnQcEvJlxuWVxDhk0MOuU0YWO8AbYZF9k9cRz105+A8UYhHVDH6mkBvNGX 2OAm3YMW82Hl+BJmnuE8TafRVK/YLC0Hnw2IM8CTYl+eEReP+/P1MIYxH4C0yjoekmLmDbDMj Gt5wEkMlN4lND6xrL0g2izS1JxoMOC4Z5LOZ4XW0XIueYFUUAJn2o7cJMwJO4UpbXCPpcU6os dBlbisZ//Gf/SpzrBtimTbLJ2kntZcNFxKNgOdKPv/DWoewsuy3a/ncV+KTbqfjp6aQ3CgD7q 3/dpGE3TmdkC/v6ivsJ+RJR3a2wxHLVhZhODvP70ZNrSRfM6V+tkAgvBC2xw9z9IKXWCEQHRL syjCNBkFN8s0Ctrd6zAX7fB7kT7I8l9UvuQpSpBhRYqJEbPKOQ4E4rWtMmIQe0QqTTaOu6kat vJ7rqjyEDnD6LpMEjXikkRaI0kc= Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Deduplicate the code for setting the options "separator" and "key_value_separator" by moving it into a new helper function, expand_separator(). Signed-off-by: René Scharfe --- pretty.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) -- 2.41.0 diff --git a/pretty.c b/pretty.c index 0bb938021b..d2df561a05 100644 --- a/pretty.c +++ b/pretty.c @@ -1250,6 +1250,17 @@ static int format_trailer_match_cb(const struct strbuf *key, void *ud) return 0; } +static struct strbuf *expand_separator(struct strbuf *sb, + const char *argval, size_t arglen) +{ + char *fmt = xstrndup(argval, arglen); + + strbuf_reset(sb); + strbuf_expand(sb, fmt, strbuf_expand_literal_cb, NULL); + free(fmt); + return sb; +} + int format_set_trailers_options(struct process_trailer_options *opts, struct string_list *filter_list, struct strbuf *sepbuf, @@ -1278,21 +1289,9 @@ int format_set_trailers_options(struct process_trailer_options *opts, opts->filter_data = filter_list; opts->only_trailers = 1; } else if (match_placeholder_arg_value(*arg, "separator", arg, &argval, &arglen)) { - char *fmt; - - strbuf_reset(sepbuf); - fmt = xstrndup(argval, arglen); - strbuf_expand(sepbuf, fmt, strbuf_expand_literal_cb, NULL); - free(fmt); - opts->separator = sepbuf; + opts->separator = expand_separator(sepbuf, argval, arglen); } else if (match_placeholder_arg_value(*arg, "key_value_separator", arg, &argval, &arglen)) { - char *fmt; - - strbuf_reset(kvsepbuf); - fmt = xstrndup(argval, arglen); - strbuf_expand(kvsepbuf, fmt, strbuf_expand_literal_cb, NULL); - free(fmt); - opts->key_value_separator = kvsepbuf; + opts->key_value_separator = expand_separator(kvsepbuf, argval, arglen); } else if (!match_placeholder_bool_arg(*arg, "only", arg, &opts->only_trailers) && !match_placeholder_bool_arg(*arg, "unfold", arg, &opts->unfold) && !match_placeholder_bool_arg(*arg, "keyonly", arg, &opts->key_only) && From patchwork Sat Jun 17 20:41:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13283726 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D368EB64D9 for ; Sat, 17 Jun 2023 20:42:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236059AbjFQUmK (ORCPT ); Sat, 17 Jun 2023 16:42:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346479AbjFQUly (ORCPT ); Sat, 17 Jun 2023 16:41:54 -0400 Received: from mout.web.de (mout.web.de [212.227.15.14]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ADA6A273F for ; Sat, 17 Jun 2023 13:41:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=s29768273; t=1687034505; x=1687639305; i=l.s.r@web.de; bh=ht5KXuXk5pLUdtGbukC0JzfUgKE3ms8w9nPNRaFyI4g=; h=X-UI-Sender-Class:Date:Subject:From:To:References:In-Reply-To; b=pWaRGffz9ug2HAdsAZUXqyKdeE7IQv5S4x7kF+/bTKNJ6TPa0Gf7onjxAZXoHwUw8mpn4cY rtJ406f44O362idyOJ8RIM6vhd9Tm8t3Y4pM+JG7dlvsdTH2A66LOYVtS/GtKNTyeXX8wHxNJ ftaBKDbpv2ISxinKHighnOt35+NSG/jhlmSuh5Ab8BR8x398aE9CJ8pSq+t9n/XJWK6wX+GKi 4aeVxOkB3FhY5+Q/W7Gck84O4kZE7i+mUWC8tyD4wxWPpocn7LVCPyVGT5UhLbIY+gnTqwXsl AgKQDdEK6whDizXNis68qVDl9Lr5YZknFML07LlKF/ot7nuVInFQ== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([91.47.157.195]) by smtp.web.de (mrweb005 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MpTxo-1plTXg3hTY-00qA99 for ; Sat, 17 Jun 2023 22:41:44 +0200 Message-ID: Date: Sat, 17 Jun 2023 22:41:44 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 Subject: [PATCH 2/5] strbuf: factor out strbuf_expand_step() Content-Language: en-US From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List References: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> In-Reply-To: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> X-Provags-ID: V03:K1:Cg1avrKVw8NBU0fB4/CSzFvfkBarAVnCXBQHbN/JnNNedqylKvm HU/xje/5k/vPkY464PF/bO83pxUPlJ/QKfcAh8pvawW5t+g/ouOcH2BlOHAuXy+HyzhgZEX GMD2xFzkvSSlo53mPo594BxQ2Pq4HyuUDDvLBHtf8jw1PaynwcfFRKZGje/0i02X7u0Q2Rt NDfhT6xR5tHP3qWN/NlzQ== UI-OutboundReport: notjunk:1;M01:P0:QJEY+Bu9xaM=;0uld1VjVtGAKSS+0CWUT2zzikgV vyce5p5XOhLq9Em5JGofz7ARLiys7fvt84wquhsNTy/Dwp3/+8upqwd/m1R0v01MTrdOLh1Pu uy5qTLxqiQPeWOrzQenttQZ+pJoBTIaf3pkrGAJ6xIVssUNiSv8KjfVbqxxEO8CzRJ7KSYFSz 5M6uqIYjHVsJFiFUOTPbg9Uowa3bXSOFreVzUjvl/eeTHSRuF7gb15RjB8kyMsalnicqC+VTL NElv++B9xwulij/OWGxOF57zux6lPmYGMLEoUUxSa7Z1xlVvNTefsuvLcrKkLrASFrXjkf1VB Wsk0NGUGUvPEJb/dVpCg+qoHTNIqEm2wSl37xQyfZj5vRtunOINkvjGCkJIu53U3agzOmxkSZ j+76mIhaXCp//lyOQJ1RrsuMGY8l9JmPrSL/sT4aUbkOAp85E1LcLI5d1ILa60ger08Cqr5xX rDnf9c7LooKl+xPbNbkmvWkSuNDhHaSdK06sO/98i7vRO93S3Oc1Y5+0LxhZOS79WpTBnggiM AkrkEFoKhmPVCbjmVF23b8NVRU1v5zh+M+TGL7EnsTp90cRdvaq2GMEfOlELgf2HOeWqpIw22 Hv4XHxv6XhdtPtmfVxm9hKFkY9eyfbuAiL5Vdlg38OPnBQCqghiqrrbGgXGNEL3NUqLVW7mlx Ndy2hLOgoNcBBbHwilbAe+u0kr+FcY6fKqEuOq+Ugss0MIlzDCjRLs2WXFz1tCI1pnr6VD9Mg XvJIm5g0dvBkhGQBkympqJmWGMYjwd2rVGG/ulRmHJhJfNdC5YJSwtxbLPYzKn3ILnI1zgsAb xw7quwXgDlrIMGc/twpEOIs/8BAz0DYYvS8rMmKAjZrADknjdcr28EPoSzWHGFFn87DQ1nrtf BBbYeh8hxyO7n/EsG7lyQc6POW/nqlaZRKHEgf9RPr45/2U03SbMsu/fR110AJ4qVhA4s7vUA thmODgR/HSYIMSGPmVVGRebv5Ps= Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Extract the part of strbuf_expand that finds the next placeholder into a new function. It allows to build parsers without callback functions and the overhead imposed by them. Signed-off-by: René Scharfe --- builtin/branch.c | 13 ++----------- strbuf.c | 28 ++++++++++++++-------------- strbuf.h | 8 ++++++++ 3 files changed, 24 insertions(+), 25 deletions(-) -- 2.41.0 diff --git a/builtin/branch.c b/builtin/branch.c index e6c2655af6..7c20e049a2 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -366,17 +366,8 @@ static const char *quote_literal_for_format(const char *s) static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - while (*s) { - const char *ep = strchrnul(s, '%'); - if (s < ep) - strbuf_add(&buf, s, ep - s); - if (*ep == '%') { - strbuf_addstr(&buf, "%%"); - s = ep + 1; - } else { - s = ep; - } - } + while (strbuf_expand_step(&buf, &s)) + strbuf_addstr(&buf, "%%"); return buf.buf; } diff --git a/strbuf.c b/strbuf.c index 08eec8f1d8..a90b597da1 100644 --- a/strbuf.c +++ b/strbuf.c @@ -415,19 +415,24 @@ void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap) strbuf_setlen(sb, sb->len + len); } +int strbuf_expand_step(struct strbuf *sb, const char **formatp) +{ + const char *format = *formatp; + const char *percent = strchrnul(format, '%'); + + strbuf_add(sb, format, percent - format); + if (!*percent) + return 0; + *formatp = percent + 1; + return 1; +} + void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context) { - for (;;) { - const char *percent; + while (strbuf_expand_step(sb, &format)) { size_t consumed; - percent = strchrnul(format, '%'); - strbuf_add(sb, format, percent - format); - if (!*percent) - break; - format = percent + 1; - if (*format == '%') { strbuf_addch(sb, '%'); format++; @@ -1022,12 +1027,7 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm, * we want for %z, but the computation for %s has to convert to number * of seconds. */ - for (;;) { - const char *percent = strchrnul(fmt, '%'); - strbuf_add(&munged_fmt, fmt, percent - fmt); - if (!*percent) - break; - fmt = percent + 1; + while (strbuf_expand_step(&munged_fmt, &fmt)) { switch (*fmt) { case '%': strbuf_addstr(&munged_fmt, "%%"); diff --git a/strbuf.h b/strbuf.h index 3dfeadb44c..a189f12b84 100644 --- a/strbuf.h +++ b/strbuf.h @@ -371,6 +371,14 @@ size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context); +/** + * If the string pointed to by `formatp` contains a percent sign ("%"), + * advance it to point to the character following the next one and + * return 1, otherwise return 0. Append the substring before that + * percent sign to `sb`, or the whole string if there is none. + */ +int strbuf_expand_step(struct strbuf *sb, const char **formatp); + /** * Append the contents of one strbuf to another, quoting any * percent signs ("%") into double-percents ("%%") in the From patchwork Sat Jun 17 20:42:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13283727 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E0E3EB64DB for ; Sat, 17 Jun 2023 20:42:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232540AbjFQUmj (ORCPT ); Sat, 17 Jun 2023 16:42:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233497AbjFQUmi (ORCPT ); Sat, 17 Jun 2023 16:42:38 -0400 Received: from mout.web.de (mout.web.de [212.227.15.4]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C7A91737 for ; Sat, 17 Jun 2023 13:42:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=s29768273; t=1687034547; x=1687639347; i=l.s.r@web.de; bh=VmtRWsVu4LfqGqKoZxlALNZjOvRBXNUNAQW8uav2GBE=; h=X-UI-Sender-Class:Date:Subject:From:To:References:In-Reply-To; b=jW0zavBe/SxNOHmuVA57SF4fZUhgXQIhLNGwKE3codZmkvfxJQllAzChVgTwR1fTPEfBy3f kEnlHV62ZRTQekwZdDr7F8H7if+uevfkQfRdGgTWPsEfzmUpJxta0uixKAVHDuXhOuurWjY9U oIzXjC84emOzXxREnUo0xYbFuAJJukazDkYrZwpAykwN/ApgKTZOqleAzG5FnNr4gneqtwNmp 0EYcVq0LRGNgJT0F2hqzjfdObE6G6vJLX1CqBoesBkeAVdnaLSpRCMHas2TMEGBnxZYMdv422 OQ63zlcpr/fmxh5lpy9wlLlcBkEoElo0so5haCzbZ5yFlwy/ETxQ== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([91.47.157.195]) by smtp.web.de (mrweb005 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MN6FV-1qRTLb449d-00ImLB for ; Sat, 17 Jun 2023 22:42:27 +0200 Message-ID: <5ce9513b-d463-6f62-db4e-f9f60a7c3e9f@web.de> Date: Sat, 17 Jun 2023 22:42:26 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 Subject: [PATCH 3/5] replace strbuf_expand_dict_cb() with strbuf_expand_step() Content-Language: en-US From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List References: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> In-Reply-To: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> X-Provags-ID: V03:K1:99djNyvDpVPjN97QcnRy1s4LxDWzlyRsnVgEWN4pCgJ7xX1btkr 7Md245VIxHRrTuXDHvdG/oYmg7LWB2epizK+GqEiDpdxKrIogZI514aHGMKTOUlsqWXjgOQ ukESXyFf9W1/Qk78xz4kGI2NoqRs6E6rSPrGOFujBrgFBJiQWdol3sqXuGpgS4StmJfbUwV H9ME17JPhMHpLBXFpkG+w== UI-OutboundReport: notjunk:1;M01:P0:SMVzP8AvlvQ=;P4i3dPiXkhZywoLKHJM9C6SmDi3 o579yMyyvqILX58k2uCgIN8YsjEMY3bdyR+30sDWY64F/nu4nCkWDpUnKKQaQmbs7WMFu1S1e N6NoD5rRZnyAPAFEpemmO285eu+5Cc46bxELzjhq+NL90AGQ+DnF9YLMungjh4JAvn2aGSVKW +isvqStJuW7NmjipfLGq8Za4vktX70w2WoCroeE4KhDrGWTcDszvnMApIQKsSe5yQCYhEN/9Y SgMcokZsyHyz4T7d8N4EveSaoQ19eKTikAUxV/OZ5cmMvEYcTB4WdozDzFRfX3ZKWVThRzZjX gLAe4vrj5NPSv5RlRmc3vOxgFwTs6aGwZ5+3L+BM2rWr7EWXIYByFveHEItz28aPETdE+9vTk P/vj5C/a0KHai21i/ls/nKpNxDQJoJQ3LPLHjQtJNz0AdOR1HBsocMX/qQIT4Yh4sy56pvAfM bZy+4vABkQ1pNAD/FSdxyqRTq72AsM2Xi/+rEBOwZnnwiv975xO2wV6cofUQX7UlhpBg59EFW c49acqgKDYz5oSNwZxNFps/hMsYT/HPn9XpRNT51jGz0QaSIFf+ThFsSCrW5wzAUgyN71CUBI S0Pp2nwiyt7ruhZtkp01yc5AS6+QNz2Y8A9W4yF1RdnuoJ2ePSqZWPn8xn3ud2XcztFxJX38N TSwE/VPmgn8eX3wdx08w7j2ZW48rATV9JTK5R7/k6qAf3tsIFh4joSIMr3xzpdByfcIR3QMjn RsLXxMAwg9tTZGdLqLU9soOjvQEiU37U61Vnp/30gOW3IKKc+QafOQe1vfSyZQPwGGDPhY/g+ LWdQeixtjHxrZeZEQPI4WhQVMHlxWM8KSWoERhNMLa8vBwakC9/0lCeUF4BbdXpyIg6u0nXSi v2sTHPw1lOTjLsik1tXStQg8b4ImWNpHRE8rnBHXoKD+nWFeIo5mFzJh4BIK3NnxpD1jZDG56 P3vjLKuHTNHxkP4HQRdYpst5nKk= Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Avoid the overhead of setting up a dictionary and passing it via strbuf_expand() to strbuf_expand_dict_cb() by using strbuf_expand_step() in a loop instead. It requires explicit handling of %% and unrecognized placeholders, but is more direct and simpler overall, and expands only on demand. Signed-off-by: René Scharfe --- convert.c | 22 ++++++++++------------ ll-merge.c | 32 ++++++++++++++++++-------------- strbuf.c | 16 ---------------- strbuf.h | 14 -------------- 4 files changed, 28 insertions(+), 56 deletions(-) -- 2.41.0 diff --git a/convert.c b/convert.c index 9ee79fe469..455d05cf6b 100644 --- a/convert.c +++ b/convert.c @@ -633,23 +633,21 @@ static int filter_buffer_or_fd(int in UNUSED, int out, void *data) */ struct child_process child_process = CHILD_PROCESS_INIT; struct filter_params *params = (struct filter_params *)data; + const char *format = params->cmd; int write_err, status; /* apply % substitution to cmd */ struct strbuf cmd = STRBUF_INIT; - struct strbuf path = STRBUF_INIT; - struct strbuf_expand_dict_entry dict[] = { - { "f", NULL, }, - { NULL, NULL, }, - }; - - /* quote the path to preserve spaces, etc. */ - sq_quote_buf(&path, params->path); - dict[0].value = path.buf; - /* expand all %f with the quoted path */ - strbuf_expand(&cmd, params->cmd, strbuf_expand_dict_cb, &dict); - strbuf_release(&path); + /* expand all %f with the quoted path; quote to preserve space, etc. */ + while (strbuf_expand_step(&cmd, &format)) { + if (skip_prefix(format, "%", &format)) + strbuf_addch(&cmd, '%'); + else if (skip_prefix(format, "f", &format)) + sq_quote_buf(&cmd, params->path); + else + strbuf_addch(&cmd, '%'); + } strvec_push(&child_process.args, cmd.buf); child_process.use_shell = 1; diff --git a/ll-merge.c b/ll-merge.c index 07ec16e8e5..b307ad293c 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -192,24 +192,15 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn, const struct ll_merge_options *opts, int marker_size) { - char temp[4][50]; + char temp[3][50]; struct strbuf cmd = STRBUF_INIT; - struct strbuf_expand_dict_entry dict[6]; - struct strbuf path_sq = STRBUF_INIT; + const char *format = fn->cmdline; struct child_process child = CHILD_PROCESS_INIT; int status, fd, i; struct stat st; enum ll_merge_result ret; assert(opts); - sq_quote_buf(&path_sq, path); - dict[0].placeholder = "O"; dict[0].value = temp[0]; - dict[1].placeholder = "A"; dict[1].value = temp[1]; - dict[2].placeholder = "B"; dict[2].value = temp[2]; - dict[3].placeholder = "L"; dict[3].value = temp[3]; - dict[4].placeholder = "P"; dict[4].value = path_sq.buf; - dict[5].placeholder = NULL; dict[5].value = NULL; - if (!fn->cmdline) die("custom merge driver %s lacks command line.", fn->name); @@ -218,9 +209,23 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn, create_temp(orig, temp[0], sizeof(temp[0])); create_temp(src1, temp[1], sizeof(temp[1])); create_temp(src2, temp[2], sizeof(temp[2])); - xsnprintf(temp[3], sizeof(temp[3]), "%d", marker_size); - strbuf_expand(&cmd, fn->cmdline, strbuf_expand_dict_cb, &dict); + while (strbuf_expand_step(&cmd, &format)) { + if (skip_prefix(format, "%", &format)) + strbuf_addch(&cmd, '%'); + else if (skip_prefix(format, "O", &format)) + strbuf_addstr(&cmd, temp[0]); + else if (skip_prefix(format, "A", &format)) + strbuf_addstr(&cmd, temp[1]); + else if (skip_prefix(format, "B", &format)) + strbuf_addstr(&cmd, temp[2]); + else if (skip_prefix(format, "L", &format)) + strbuf_addf(&cmd, "%d", marker_size); + else if (skip_prefix(format, "P", &format)) + sq_quote_buf(&cmd, path); + else + strbuf_addch(&cmd, '%'); + } child.use_shell = 1; strvec_push(&child.args, cmd.buf); @@ -242,7 +247,6 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn, for (i = 0; i < 3; i++) unlink_or_warn(temp[i]); strbuf_release(&cmd); - strbuf_release(&path_sq); ret = (status > 0) ? LL_MERGE_CONFLICT : status; return ret; } diff --git a/strbuf.c b/strbuf.c index a90b597da1..972366b410 100644 --- a/strbuf.c +++ b/strbuf.c @@ -468,22 +468,6 @@ size_t strbuf_expand_literal_cb(struct strbuf *sb, return 0; } -size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, - void *context) -{ - struct strbuf_expand_dict_entry *e = context; - size_t len; - - for (; e->placeholder && (len = strlen(e->placeholder)); e++) { - if (!strncmp(placeholder, e->placeholder, len)) { - if (e->value) - strbuf_addstr(sb, e->value); - return len; - } - } - return 0; -} - void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src) { size_t i, len = src->len; diff --git a/strbuf.h b/strbuf.h index a189f12b84..e293117f07 100644 --- a/strbuf.h +++ b/strbuf.h @@ -357,20 +357,6 @@ size_t strbuf_expand_literal_cb(struct strbuf *sb, const char *placeholder, void *context); -/** - * Used as callback for `strbuf_expand()`, expects an array of - * struct strbuf_expand_dict_entry as context, i.e. pairs of - * placeholder and replacement string. The array needs to be - * terminated by an entry with placeholder set to NULL. - */ -struct strbuf_expand_dict_entry { - const char *placeholder; - const char *value; -}; -size_t strbuf_expand_dict_cb(struct strbuf *sb, - const char *placeholder, - void *context); - /** * If the string pointed to by `formatp` contains a percent sign ("%"), * advance it to point to the character following the next one and From patchwork Sat Jun 17 20:43:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13283728 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC4C4EB64D9 for ; Sat, 17 Jun 2023 20:43:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232416AbjFQUnX (ORCPT ); Sat, 17 Jun 2023 16:43:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46660 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229446AbjFQUnW (ORCPT ); Sat, 17 Jun 2023 16:43:22 -0400 Received: from mout.web.de (mout.web.de [212.227.15.14]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64876100 for ; Sat, 17 Jun 2023 13:43:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=s29768273; t=1687034597; x=1687639397; i=l.s.r@web.de; bh=tgptdcUzXi99wTKXokTVpV9uxwmfPepeNmVGK+wJiOI=; h=X-UI-Sender-Class:Date:Subject:From:To:References:In-Reply-To; b=jMbM7VNbQcRvIUyOLWSXSzMv07bHiR/7ASivW9pYM8Eabog8IcpVhyk7e0fbBU0MQVrLoz7 ZUeEXZuXbQPp7Vut3KRAeVFE7HidWUHhRWSMEGz5ayDcOLdQnVSRHY22cUWXOKYQxO9g8wJ17 K/CYoTs1Xi7j2BA8D3we7VyjvDq5uANx5mNs5dUoTOuRgMgyKjNv1NpNClAa4AZXX88lGCT19 8UY5bcstlwtAOv7GL7juz/t9ov9RcEqRWdbgvFLIyh5WyXRMcT6uwBf/7vsjoRtIlC4Q1pKMF ipaOxi0XDbYpOgv1oH0qdxh082XYNvjrPE1W/Z+RF2PN1Osl1ClA== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([91.47.157.195]) by smtp.web.de (mrweb005 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MgAJ8-1pc5dL2qOE-00hsen for ; Sat, 17 Jun 2023 22:43:17 +0200 Message-ID: <150df0b0-0548-f291-2b68-960841dd1c97@web.de> Date: Sat, 17 Jun 2023 22:43:17 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 Subject: [PATCH 4/5] replace strbuf_expand() with strbuf_expand_step() Content-Language: en-US From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List References: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> In-Reply-To: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> X-Provags-ID: V03:K1:4HVFmAZpigKGmVZtEWZCb80paqi2ezhmdHk8O+76RLfLLLjYo7V ZEiU9uPe2asERBxuK275i7rtFLmU7zEnpzgoZmrXyMWoxAA6Ua4YTLSBEis84iqfobX1D8o r8j3jOau3AfCpTxU6AOnUw0uaUhXiXUpO+OnJsAGDGWoMEK8ParaMzutVLeDgF817FAYSW9 v7wcri6WOVnj7o2PgKxcw== UI-OutboundReport: notjunk:1;M01:P0:PXIe1365S08=;deTiHhC4Mhn0kAWqBoFuEocSxKE HygCjmDnKkB/PZefeu02ntUSdKzcjCiTu5WiaIS/t229RE5WS5kLg7qv7XaOduYt2+jA78vFu iNeuqiTEaliVrzqH07VlA/TxB5aJOmrPHX3buUQpcrWqHyLDj/bVRmbVJPnX2/l3xJzO4tWxW 6lE0eeG+smIP3KnnRMVrdGFSTufK/GTdWbDDjhRY7YB4ElEkn53lnTA6G9/aS33V5SM95IHN7 zV4j0SwX4wGF1NJmCXWETOYq6Y5gu0kbQPNcdYCDaS6el/Q4p/fFcpztTX2thB9IJUHlllack /euKW0IGtYCxbuxKGVWG9TQDHZnkO1s3nD0io5I/5OZsUBdFN/iVmqNt6d9tgZK4q8AUwXzIO DET5IUbUJJWDCFkaWy/yz8/LbcxS73zktPnxQycH5nfIuiwMluBbjtWV+O3xTYs2GNW62fP7z BydEx/B/H7JRU5fo6fVLNQuu/f6Gpk2B0HifqHoWhiTbn07U0JF1IsMZkfJdtOLE3br3AJzSa AHE9pzeand3nYxbQterSQjAIPFjO3QSrXF6EyKtYNUc5qP97tEn9X7qDXFW6dx9V5gAJFzWoM 9ItXTHHEkGdl4fwolLytSdNF35xEBDm1b3B621Ex/J/zm5PMJX7CtPIpYzit+BFDY/64RFO08 h3byflxuWrBdMh1/X4tje96QubO0W1/u/4C7NGSDkNpoiUeEq6xPT4vKYeER8Ec37lmyobzUk EtfiHHMY9vTY/WqxMmOencO2kbC4afNGd5ZxoNRSujJOe4QZEIMnFXyHsPC+Nys4NZwWu6Io8 r8RIfPDFm6kF59XjnaUf2zc95U6sLV7UqGS5+OIGO/utSQUCCBPkCI8NGh+LRI5+o5jV0oMQK RFYyABaObX1zmWJFAtkqMilVYkSNo4Fa1RCkxSb1ONOtmUd1rekQ9lQKO2pqSRIT6H3ElEhZd MYC42w== Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Avoid the overhead of passing context to a callback function of strbuf_expand() by using strbuf_expand_step() in a loop instead. It requires explicit handling of %% and unrecognized placeholders, but is simpler, more direct and avoids void pointers. Signed-off-by: René Scharfe --- builtin/cat-file.c | 35 +++++++-------- builtin/ls-files.c | 109 +++++++++++++++++++-------------------------- builtin/ls-tree.c | 107 +++++++++++++++++--------------------------- daemon.c | 61 ++++++++----------------- pretty.c | 72 ++++++++++++++++++------------ strbuf.c | 20 --------- strbuf.h | 37 ++------------- 7 files changed, 169 insertions(+), 272 deletions(-) -- 2.41.0 diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 0bafc14e6c..424f39675b 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -309,10 +309,8 @@ static int is_atom(const char *atom, const char *s, int slen) } static void expand_atom(struct strbuf *sb, const char *atom, int len, - void *vdata) + struct expand_data *data) { - struct expand_data *data = vdata; - if (is_atom("objectname", atom, len)) { if (!data->mark_query) strbuf_addstr(sb, oid_to_hex(&data->oid)); @@ -346,19 +344,21 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len, die("unknown format element: %.*s", len, atom); } -static size_t expand_format(struct strbuf *sb, const char *start, void *data) +static void expand_format(struct strbuf *sb, const char *start, + struct expand_data *data) { - const char *end; - - if (*start != '(') - return 0; - end = strchr(start + 1, ')'); - if (!end) - die("format element '%s' does not end in ')'", start); - - expand_atom(sb, start + 1, end - start - 1, data); - - return end - start + 1; + while (strbuf_expand_step(sb, &start)) { + const char *end; + + if (skip_prefix(start, "%", &start) || *start != '(') + strbuf_addch(sb, '%'); + else if (!(end = strchr(start + 1, ')'))) + die("format element '%s' does not end in ')'", start); + else { + expand_atom(sb, start + 1, end - start - 1, data); + start = end + 1; + } + } } static void batch_write(struct batch_options *opt, const void *data, int len) @@ -494,7 +494,7 @@ static void batch_object_write(const char *obj_name, if (!opt->format) { print_default_format(scratch, data); } else { - strbuf_expand(scratch, opt->format, expand_format, data); + expand_format(scratch, opt->format, data); strbuf_addch(scratch, '\n'); } @@ -777,9 +777,8 @@ static int batch_objects(struct batch_options *opt) */ memset(&data, 0, sizeof(data)); data.mark_query = 1; - strbuf_expand(&output, + expand_format(&output, opt->format ? opt->format : DEFAULT_FORMAT, - expand_format, &data); data.mark_query = 0; strbuf_release(&output); diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 72012c0f0f..03bf5771b4 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -262,74 +262,57 @@ static void expand_objectsize(struct strbuf *line, const struct object_id *oid, strbuf_addstr(line, "-"); } } -struct show_index_data { - const char *pathname; - struct index_state *istate; - const struct cache_entry *ce; -}; - -static size_t expand_show_index(struct strbuf *sb, const char *start, - void *context) -{ - struct show_index_data *data = context; - const char *end; - const char *p; - size_t len = strbuf_expand_literal_cb(sb, start, NULL); - struct stat st; - - if (len) - return len; - if (*start != '(') - die(_("bad ls-files format: element '%s' " - "does not start with '('"), start); - - end = strchr(start + 1, ')'); - if (!end) - die(_("bad ls-files format: element '%s' " - "does not end in ')'"), start); - - len = end - start + 1; - if (skip_prefix(start, "(objectmode)", &p)) - strbuf_addf(sb, "%06o", data->ce->ce_mode); - else if (skip_prefix(start, "(objectname)", &p)) - strbuf_add_unique_abbrev(sb, &data->ce->oid, abbrev); - else if (skip_prefix(start, "(objecttype)", &p)) - strbuf_addstr(sb, type_name(object_type(data->ce->ce_mode))); - else if (skip_prefix(start, "(objectsize:padded)", &p)) - expand_objectsize(sb, &data->ce->oid, object_type(data->ce->ce_mode), 1); - else if (skip_prefix(start, "(objectsize)", &p)) - expand_objectsize(sb, &data->ce->oid, object_type(data->ce->ce_mode), 0); - else if (skip_prefix(start, "(stage)", &p)) - strbuf_addf(sb, "%d", ce_stage(data->ce)); - else if (skip_prefix(start, "(eolinfo:index)", &p)) - strbuf_addstr(sb, S_ISREG(data->ce->ce_mode) ? - get_cached_convert_stats_ascii(data->istate, - data->ce->name) : ""); - else if (skip_prefix(start, "(eolinfo:worktree)", &p)) - strbuf_addstr(sb, !lstat(data->pathname, &st) && - S_ISREG(st.st_mode) ? - get_wt_convert_stats_ascii(data->pathname) : ""); - else if (skip_prefix(start, "(eolattr)", &p)) - strbuf_addstr(sb, get_convert_attr_ascii(data->istate, - data->pathname)); - else if (skip_prefix(start, "(path)", &p)) - write_name_to_buf(sb, data->pathname); - else - die(_("bad ls-files format: %%%.*s"), (int)len, start); - - return len; -} static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce, const char *format, const char *fullname) { - struct show_index_data data = { - .pathname = fullname, - .istate = repo->index, - .ce = ce, - }; struct strbuf sb = STRBUF_INIT; - strbuf_expand(&sb, format, expand_show_index, &data); + while (strbuf_expand_step(&sb, &format)) { + const char *end; + size_t len; + struct stat st; + + if (skip_prefix(format, "%", &format)) + strbuf_addch(&sb, '%'); + else if ((len = strbuf_expand_literal_cb(&sb, format, NULL))) + format += len; + else if (*format != '(') + die(_("bad ls-files format: element '%s' " + "does not start with '('"), format); + else if (!(end = strchr(format + 1, ')'))) + die(_("bad ls-files format: element '%s' " + "does not end in ')'"), format); + else if (skip_prefix(format, "(objectmode)", &format)) + strbuf_addf(&sb, "%06o", ce->ce_mode); + else if (skip_prefix(format, "(objectname)", &format)) + strbuf_add_unique_abbrev(&sb, &ce->oid, abbrev); + else if (skip_prefix(format, "(objecttype)", &format)) + strbuf_addstr(&sb, type_name(object_type(ce->ce_mode))); + else if (skip_prefix(format, "(objectsize:padded)", &format)) + expand_objectsize(&sb, &ce->oid, + object_type(ce->ce_mode), 1); + else if (skip_prefix(format, "(objectsize)", &format)) + expand_objectsize(&sb, &ce->oid, + object_type(ce->ce_mode), 0); + else if (skip_prefix(format, "(stage)", &format)) + strbuf_addf(&sb, "%d", ce_stage(ce)); + else if (skip_prefix(format, "(eolinfo:index)", &format)) + strbuf_addstr(&sb, S_ISREG(ce->ce_mode) ? + get_cached_convert_stats_ascii(repo->index, + ce->name) : ""); + else if (skip_prefix(format, "(eolinfo:worktree)", &format)) + strbuf_addstr(&sb, !lstat(fullname, &st) && + S_ISREG(st.st_mode) ? + get_wt_convert_stats_ascii(fullname) : ""); + else if (skip_prefix(format, "(eolattr)", &format)) + strbuf_addstr(&sb, get_convert_attr_ascii(repo->index, + fullname)); + else if (skip_prefix(format, "(path)", &format)) + write_name_to_buf(&sb, fullname); + else + die(_("bad ls-files format: %%%.*s"), + (int)(end - format + 1), format); + } strbuf_addch(&sb, line_terminator); fwrite(sb.buf, sb.len, 1, stdout); strbuf_release(&sb); diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 077977a461..8460d20257 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -55,63 +55,6 @@ struct ls_tree_options { const char *format; }; -struct show_tree_data { - struct ls_tree_options *options; - unsigned mode; - enum object_type type; - const struct object_id *oid; - const char *pathname; - struct strbuf *base; -}; - -static size_t expand_show_tree(struct strbuf *sb, const char *start, - void *context) -{ - struct show_tree_data *data = context; - struct ls_tree_options *options = data->options; - const char *end; - const char *p; - unsigned int errlen; - size_t len = strbuf_expand_literal_cb(sb, start, NULL); - - if (len) - return len; - if (*start != '(') - die(_("bad ls-tree format: element '%s' does not start with '('"), start); - - end = strchr(start + 1, ')'); - if (!end) - die(_("bad ls-tree format: element '%s' does not end in ')'"), start); - - len = end - start + 1; - if (skip_prefix(start, "(objectmode)", &p)) { - strbuf_addf(sb, "%06o", data->mode); - } else if (skip_prefix(start, "(objecttype)", &p)) { - strbuf_addstr(sb, type_name(data->type)); - } else if (skip_prefix(start, "(objectsize:padded)", &p)) { - expand_objectsize(sb, data->oid, data->type, 1); - } else if (skip_prefix(start, "(objectsize)", &p)) { - expand_objectsize(sb, data->oid, data->type, 0); - } else if (skip_prefix(start, "(objectname)", &p)) { - strbuf_add_unique_abbrev(sb, data->oid, options->abbrev); - } else if (skip_prefix(start, "(path)", &p)) { - const char *name = data->base->buf; - const char *prefix = options->chomp_prefix ? options->ls_tree_prefix : NULL; - struct strbuf sbuf = STRBUF_INIT; - size_t baselen = data->base->len; - - strbuf_addstr(data->base, data->pathname); - name = relative_path(data->base->buf, prefix, &sbuf); - quote_c_style(name, sb, NULL, 0); - strbuf_setlen(data->base, baselen); - strbuf_release(&sbuf); - } else { - errlen = (unsigned long)len; - die(_("bad ls-tree format: %%%.*s"), errlen, start); - } - return len; -} - static int show_recursive(struct ls_tree_options *options, const char *base, size_t baselen, const char *pathname) { @@ -150,14 +93,7 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base, int recurse = 0; struct strbuf sb = STRBUF_INIT; enum object_type type = object_type(mode); - struct show_tree_data cb_data = { - .options = options, - .mode = mode, - .type = type, - .oid = oid, - .pathname = pathname, - .base = base, - }; + const char *format = options->format; if (type == OBJ_TREE && show_recursive(options, base->buf, base->len, pathname)) recurse = READ_TREE_RECURSIVE; @@ -166,7 +102,46 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base, if (type == OBJ_BLOB && (options->ls_options & LS_TREE_ONLY)) return 0; - strbuf_expand(&sb, options->format, expand_show_tree, &cb_data); + while (strbuf_expand_step(&sb, &format)) { + const char *end; + size_t len; + + if (skip_prefix(format, "%", &format)) + strbuf_addch(&sb, '%'); + else if ((len = strbuf_expand_literal_cb(&sb, format, NULL))) + format += len; + else if (*format != '(') + die(_("bad ls-tree format: element '%s' " + "does not start with '('"), format); + else if (!(end = strchr(format + 1, ')'))) + die(_("bad ls-tree format: element '%s' " + "does not end in ')'"), format); + else if (skip_prefix(format, "(objectmode)", &format)) + strbuf_addf(&sb, "%06o", mode); + else if (skip_prefix(format, "(objecttype)", &format)) + strbuf_addstr(&sb, type_name(type)); + else if (skip_prefix(format, "(objectsize:padded)", &format)) + expand_objectsize(&sb, oid, type, 1); + else if (skip_prefix(format, "(objectsize)", &format)) + expand_objectsize(&sb, oid, type, 0); + else if (skip_prefix(format, "(objectname)", &format)) + strbuf_add_unique_abbrev(&sb, oid, options->abbrev); + else if (skip_prefix(format, "(path)", &format)) { + const char *name; + const char *prefix = options->chomp_prefix ? + options->ls_tree_prefix : NULL; + struct strbuf sbuf = STRBUF_INIT; + size_t baselen = base->len; + + strbuf_addstr(base, pathname); + name = relative_path(base->buf, prefix, &sbuf); + quote_c_style(name, &sb, NULL, 0); + strbuf_setlen(base, baselen); + strbuf_release(&sbuf); + } else + die(_("bad ls-tree format: %%%.*s"), + (int)(end - format + 1), format); + } strbuf_addch(&sb, options->null_termination ? '\0' : '\n'); fwrite(sb.buf, sb.len, 1, stdout); strbuf_release(&sb); diff --git a/daemon.c b/daemon.c index 7139cc201d..3682bfdd08 100644 --- a/daemon.c +++ b/daemon.c @@ -144,42 +144,6 @@ static void NORETURN daemon_die(const char *err, va_list params) exit(1); } -struct expand_path_context { - const char *directory; - struct hostinfo *hostinfo; -}; - -static size_t expand_path(struct strbuf *sb, const char *placeholder, void *ctx) -{ - struct expand_path_context *context = ctx; - struct hostinfo *hi = context->hostinfo; - - switch (placeholder[0]) { - case 'H': - strbuf_addbuf(sb, &hi->hostname); - return 1; - case 'C': - if (placeholder[1] == 'H') { - strbuf_addstr(sb, get_canon_hostname(hi)); - return 2; - } - break; - case 'I': - if (placeholder[1] == 'P') { - strbuf_addstr(sb, get_ip_address(hi)); - return 2; - } - break; - case 'P': - strbuf_addbuf(sb, &hi->tcp_port); - return 1; - case 'D': - strbuf_addstr(sb, context->directory); - return 1; - } - return 0; -} - static const char *path_ok(const char *directory, struct hostinfo *hi) { static char rpath[PATH_MAX]; @@ -223,10 +187,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) } else if (interpolated_path && hi->saw_extended_args) { struct strbuf expanded_path = STRBUF_INIT; - struct expand_path_context context; - - context.directory = directory; - context.hostinfo = hi; + const char *format = interpolated_path; if (*dir != '/') { /* Allow only absolute */ @@ -234,8 +195,24 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) return NULL; } - strbuf_expand(&expanded_path, interpolated_path, - expand_path, &context); + while (strbuf_expand_step(&expanded_path, &format)) { + if (skip_prefix(format, "%", &format)) + strbuf_addch(&expanded_path, '%'); + else if (skip_prefix(format, "H", &format)) + strbuf_addbuf(&expanded_path, &hi->hostname); + else if (skip_prefix(format, "CH", &format)) + strbuf_addstr(&expanded_path, + get_canon_hostname(hi)); + else if (skip_prefix(format, "IP", &format)) + strbuf_addstr(&expanded_path, + get_ip_address(hi)); + else if (skip_prefix(format, "P", &format)) + strbuf_addbuf(&expanded_path, &hi->tcp_port); + else if (skip_prefix(format, "D", &format)) + strbuf_addstr(&expanded_path, directory); + else + strbuf_addch(&expanded_path, '%'); + } rlen = strlcpy(interp_path, expanded_path.buf, sizeof(interp_path)); diff --git a/pretty.c b/pretty.c index d2df561a05..cffbf32987 100644 --- a/pretty.c +++ b/pretty.c @@ -1254,9 +1254,19 @@ static struct strbuf *expand_separator(struct strbuf *sb, const char *argval, size_t arglen) { char *fmt = xstrndup(argval, arglen); + const char *format = fmt; strbuf_reset(sb); - strbuf_expand(sb, fmt, strbuf_expand_literal_cb, NULL); + while (strbuf_expand_step(sb, &format)) { + size_t len; + + if (skip_prefix(format, "%", &format)) + strbuf_addch(sb, '%'); + else if ((len = strbuf_expand_literal_cb(sb, format, NULL))) + format += len; + else + strbuf_addch(sb, '%'); + } free(fmt); return sb; } @@ -1803,7 +1813,7 @@ static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ const char *placeholder, - void *context) + struct format_commit_context *context) { size_t consumed, orig_len; enum { @@ -1842,7 +1852,7 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ } orig_len = sb->len; - if (((struct format_commit_context *)context)->flush_type != no_flush) + if ((context)->flush_type != no_flush) consumed = format_and_pad_commit(sb, placeholder, context); else consumed = format_commit_one(sb, placeholder, context); @@ -1861,30 +1871,6 @@ static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ return consumed + 1; } -static size_t userformat_want_item(struct strbuf *sb UNUSED, - const char *placeholder, - void *context) -{ - struct userformat_want *w = context; - - if (*placeholder == '+' || *placeholder == '-' || *placeholder == ' ') - placeholder++; - - switch (*placeholder) { - case 'N': - w->notes = 1; - break; - case 'S': - w->source = 1; - break; - case 'd': - case 'D': - w->decorate = 1; - break; - } - return 0; -} - void userformat_find_requirements(const char *fmt, struct userformat_want *w) { struct strbuf dummy = STRBUF_INIT; @@ -1894,7 +1880,26 @@ void userformat_find_requirements(const char *fmt, struct userformat_want *w) return; fmt = user_format; } - strbuf_expand(&dummy, fmt, userformat_want_item, w); + while (strbuf_expand_step(&dummy, &fmt)) { + if (skip_prefix(fmt, "%", &fmt)) + continue; + + if (*fmt == '+' || *fmt == '-' || *fmt == ' ') + fmt++; + + switch (*fmt) { + case 'N': + w->notes = 1; + break; + case 'S': + w->source = 1; + break; + case 'd': + case 'D': + w->decorate = 1; + break; + } + } strbuf_release(&dummy); } @@ -1912,7 +1917,16 @@ void repo_format_commit_message(struct repository *r, const char *output_enc = pretty_ctx->output_encoding; const char *utf8 = "UTF-8"; - strbuf_expand(sb, format, format_commit_item, &context); + while (strbuf_expand_step(sb, &format)) { + size_t len; + + if (skip_prefix(format, "%", &format)) + strbuf_addch(sb, '%'); + else if ((len = format_commit_item(sb, format, &context))) + format += len; + else + strbuf_addch(sb, '%'); + } rewrap_message_tail(sb, &context, 0, 0, 0); /* diff --git a/strbuf.c b/strbuf.c index 972366b410..c3d1cee616 100644 --- a/strbuf.c +++ b/strbuf.c @@ -427,26 +427,6 @@ int strbuf_expand_step(struct strbuf *sb, const char **formatp) return 1; } -void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, - void *context) -{ - while (strbuf_expand_step(sb, &format)) { - size_t consumed; - - if (*format == '%') { - strbuf_addch(sb, '%'); - format++; - continue; - } - - consumed = fn(sb, format, context); - if (consumed) - format += consumed; - else - strbuf_addch(sb, '%'); - } -} - size_t strbuf_expand_literal_cb(struct strbuf *sb, const char *placeholder, void *context UNUSED) diff --git a/strbuf.h b/strbuf.h index e293117f07..95e50e243e 100644 --- a/strbuf.h +++ b/strbuf.h @@ -318,40 +318,9 @@ const char *strbuf_join_argv(struct strbuf *buf, int argc, const char **argv, char delim); /** - * This function can be used to expand a format string containing - * placeholders. To that end, it parses the string and calls the specified - * function for every percent sign found. - * - * The callback function is given a pointer to the character after the `%` - * and a pointer to the struct strbuf. It is expected to add the expanded - * version of the placeholder to the strbuf, e.g. to add a newline - * character if the letter `n` appears after a `%`. The function returns - * the length of the placeholder recognized and `strbuf_expand()` skips - * over it. - * - * The format `%%` is automatically expanded to a single `%` as a quoting - * mechanism; callers do not need to handle the `%` placeholder themselves, - * and the callback function will not be invoked for this placeholder. - * - * All other characters (non-percent and not skipped ones) are copied - * verbatim to the strbuf. If the callback returned zero, meaning that the - * placeholder is unknown, then the percent sign is copied, too. - * - * In order to facilitate caching and to make it possible to give - * parameters to the callback, `strbuf_expand()` passes a context - * pointer with any kind of data. - */ -typedef size_t (*expand_fn_t) (struct strbuf *sb, - const char *placeholder, - void *context); -void strbuf_expand(struct strbuf *sb, - const char *format, - expand_fn_t fn, - void *context); - -/** - * Used as callback for `strbuf_expand` to only expand literals - * (i.e. %n and %xNN). The context argument is ignored. + * Used with `strbuf_expand_step` to expand the literals %n and %x + * followed by two hexadecimal digits. Returns the number of recognized + * characters. The context argument is ignored. */ size_t strbuf_expand_literal_cb(struct strbuf *sb, const char *placeholder, From patchwork Sat Jun 17 20:44:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13283729 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2427FEB64D9 for ; Sat, 17 Jun 2023 20:44:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232543AbjFQUoF (ORCPT ); Sat, 17 Jun 2023 16:44:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229446AbjFQUoD (ORCPT ); Sat, 17 Jun 2023 16:44:03 -0400 Received: from mout.web.de (mout.web.de [212.227.15.14]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82BC0B9 for ; Sat, 17 Jun 2023 13:44:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=s29768273; t=1687034641; x=1687639441; i=l.s.r@web.de; bh=XI3uVOL6CN9DEQL1+XzLwgBEUz/1lBDeHMaZO7F+ZP0=; h=X-UI-Sender-Class:Date:Subject:From:To:References:In-Reply-To; b=UJiJHLtQEsMGUlPDLIyBQymvjF1GkNuWPybwWPasu5qMY4JwybuGglKyhgOLYNlbADg386F MmpgBJH9/6oj/h30JH1Sls5MaI8vOI41gq32cG+lQl3sguR/Y3XGQ9vCkSqNBp/JhzLnJQ8xe Hjqxh/x2eqcL4Ui3ddq01M96WS+ElBMvLNgGez8EPFceAKHO7an+eeq5U4d5jJlO+VajZkiZy h1bcRDwLahQyY4uUkSqiVy1/GLqSU2VovV3/NGqJ8eGJg6CeIvbHD2GKLVTEES05AxgLaeoYE AIYcvg8BsdY2sFa7vVMIWN6yWh8WbuTjJah0uUyWR1UxVH2zowHg== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([91.47.157.195]) by smtp.web.de (mrweb005 [213.165.67.108]) with ESMTPSA (Nemesis) id 1MLRYd-1qS0w73hi7-00IEVH for ; Sat, 17 Jun 2023 22:44:00 +0200 Message-ID: Date: Sat, 17 Jun 2023 22:44:00 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.12.0 Subject: [PATCH 5/5] strbuf: simplify strbuf_expand_literal_cb() Content-Language: en-US From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List References: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> In-Reply-To: <767baa64-20a6-daf2-d34b-d81f72363749@web.de> X-Provags-ID: V03:K1:aadY49ByRNsuV5jeXeia79uETt268RowoI+I4SbLhmAAQcTRmdS Bp/w1/EuKTxVK8VbhxCuJyNcfuwiz+WiIRHANAyGpfCuKMwk9jtUsjKMhkmZVbuSKhkNkDb 8EzY5uBVXq+v8sx+JjD7O3g0j+1qWh9j2kP+Ql+Bx6TOOPp+zcnLQGZKO2p0N+uNVBmn0s5 lcamA0xkCvzMdnj1Amo7g== UI-OutboundReport: notjunk:1;M01:P0:tK+oNHxrH5c=;CEUGPIeVzo1qCTVAovZcplHlBYF IZchgcZbY5Eti4dAdBDho/UEfy8Q55RyP20CEa5Nest7mR3ea/I9Zx2GonBupPmBh82aZIW+R w5YV/QGuFKwSpRPnv/t1iJt3X5bYoPa0x1F5VKfn2e5NuWnn3Ob8vzG7JUGeqFuC5GgbejWgw au7gZWX483/XbxBebE30ZX9df/AnDWu8wdaHqAp8aQs0UK8YuixsxEfYP8tt9bs+34K4GZmhw qHiig6NZqPajjY1Y8qyD5qRD9m5HF1RSG2IgcaZ/felRFIKoz9a4atgvRVYN8LmRsB+ztWqgK +50ydMFEixrWh6kL+ozyGrAiN7JQpbbh7ic4y8XVxuWnlTwcC6y2OX0dXErFEqHAEpGdv24+Q WX1duSXKJxqCONO2WpLyxkRrGyC4hdXhsG5+yGBOkwTimPTtYKyHFAcI9yZKwZ/108G6zXjQd R9uYppzQOj+eXdh/VPIX5fvhJHsAWksNzzqhOWaL0npfQps5JNUDaIWojaMIGaNnMwQcHZZM2 kLi9OLS0luitXYSPKK6Uc6m7vLJbmycplepUKClnDquEU/tDmFSVHW0RvXwh7Lb98Npf7u5RO MhuKJgiKc2viqfKC6iBXLlndN7ic4Wr0tzhu+C8dWCPNF3yyBdh4DhX9FHZRip2AAyEQqIjzX lZPpo6dtkSi4PwcNRYv46giyJuxd/pHu7o4WuudIvxG4Qqd1SyOaNsGIHg+ZR89ojWAoMNg4A LCbY+AD8pKTSCgf/m39yDN0yaExS1prohl1kma4wU9iOILcM2TkVD9okgq1hec9dhriALRwwi /AL91gqO5OQFIVvIB3Ve28I+iPqxPJLDH7lRejMcPa2kLRgDM7oNbPuK5iTDqucCxXPJkj+3a k7hpL6A0xY7biMZxK/QlI/ic9ymQv/1F1OmiktmzQPNT8xoeiIoS+MumXvUR6FQ8E0fJcznvg KBx601UB/eMV/4c9idreTiX4Dk4= Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Now that strbuf_expand_literal_cb() is no longer used as a callback, drop its "_cb" name suffix and unused context parameter. Signed-off-by: René Scharfe --- builtin/ls-files.c | 2 +- builtin/ls-tree.c | 2 +- pretty.c | 4 ++-- strbuf.c | 4 +--- strbuf.h | 6 ++---- 5 files changed, 7 insertions(+), 11 deletions(-) -- 2.41.0 diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 03bf5771b4..0b00bd5d0f 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -274,7 +274,7 @@ static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce, if (skip_prefix(format, "%", &format)) strbuf_addch(&sb, '%'); - else if ((len = strbuf_expand_literal_cb(&sb, format, NULL))) + else if ((len = strbuf_expand_literal(&sb, format))) format += len; else if (*format != '(') die(_("bad ls-files format: element '%s' " diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 8460d20257..a90f3c81a0 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -108,7 +108,7 @@ static int show_tree_fmt(const struct object_id *oid, struct strbuf *base, if (skip_prefix(format, "%", &format)) strbuf_addch(&sb, '%'); - else if ((len = strbuf_expand_literal_cb(&sb, format, NULL))) + else if ((len = strbuf_expand_literal(&sb, format))) format += len; else if (*format != '(') die(_("bad ls-tree format: element '%s' " diff --git a/pretty.c b/pretty.c index cffbf32987..4c08f9856b 100644 --- a/pretty.c +++ b/pretty.c @@ -1262,7 +1262,7 @@ static struct strbuf *expand_separator(struct strbuf *sb, if (skip_prefix(format, "%", &format)) strbuf_addch(sb, '%'); - else if ((len = strbuf_expand_literal_cb(sb, format, NULL))) + else if ((len = strbuf_expand_literal(sb, format))) format += len; else strbuf_addch(sb, '%'); @@ -1395,7 +1395,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ char **slot; /* these are independent of the commit */ - res = strbuf_expand_literal_cb(sb, placeholder, NULL); + res = strbuf_expand_literal(sb, placeholder); if (res) return res; diff --git a/strbuf.c b/strbuf.c index c3d1cee616..55a3cfa5cf 100644 --- a/strbuf.c +++ b/strbuf.c @@ -427,9 +427,7 @@ int strbuf_expand_step(struct strbuf *sb, const char **formatp) return 1; } -size_t strbuf_expand_literal_cb(struct strbuf *sb, - const char *placeholder, - void *context UNUSED) +size_t strbuf_expand_literal(struct strbuf *sb, const char *placeholder) { int ch; diff --git a/strbuf.h b/strbuf.h index 95e50e243e..b1eab015f0 100644 --- a/strbuf.h +++ b/strbuf.h @@ -320,11 +320,9 @@ const char *strbuf_join_argv(struct strbuf *buf, int argc, /** * Used with `strbuf_expand_step` to expand the literals %n and %x * followed by two hexadecimal digits. Returns the number of recognized - * characters. The context argument is ignored. + * characters. */ -size_t strbuf_expand_literal_cb(struct strbuf *sb, - const char *placeholder, - void *context); +size_t strbuf_expand_literal(struct strbuf *sb, const char *placeholder); /** * If the string pointed to by `formatp` contains a percent sign ("%"),