From patchwork Tue Mar 3 18:13:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Girish Joshi X-Patchwork-Id: 38392 Received: (qmail 2649 invoked by alias); 3 Mar 2020 18:13:30 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 2641 invoked by uid 89); 3 Mar 2020 18:13:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=argp X-HELO: mail-wr1-f51.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=6YO+KCaejUF6AgVM3DRu6H5Qzxaja7tHYGYIych8urw=; b=JG2MQrisYmgvSwnjiSvFTeq+GXdd/1G3UImO+pvZZUhVkPC/qr2UTV15nEI2EPMgkg w142qGDwvg490HpWC/Pq5xoPpvGSUV6p9lUb0RqKaqhRbK+4LlotDPetTeAPRGCSgNWP Lbx4HWhslpfh6pOFnefxRPgqJ9J7yiCl0/ZHzYbzyqbCE+PW095/jwoWXSUdcDaL6Zzo N7wAWMh8Dbgx0fLCeJBv3Dj9stTXgZrMyYIit+ArVIDPAHm26qNVgNMaH9Kw9VjH6K82 gmBnvOoXkYvO9B0lNYhF3YHr73S5V6sRfC7iwLiAouEWniZjSSaousrBHh7Kgqoy5uUL CHYQ== MIME-Version: 1.0 From: Girish Joshi Date: Tue, 3 Mar 2020 23:43:13 +0530 Message-ID: Subject: [PATCH] argp: argp.doc prints incorrectly when it starts with "\v" [BZ #19038] To: libc-alpha@sourceware.org Hello, Reposting this patch for BZ #19038, as now I have the copyright assignment with FSF. Here the bug is that; if doc string starts with `\v` then the whole doc string is printed both before and after the options. The bug can be reproduced using following code. #include #include static char doc[] = "\vthis is post_doc"; static struct argp argp = {NULL, NULL, NULL, doc}; int main(int argc, char *args[]){ argp_parse(&argp, argc, args, 0, 0, NULL); } Currently we get the output of this code as $ argp-help --help Usage: argp-help [OPTION...] this is post_doc -?, --help Give this help list --usage Give a short usage message this is post_doc As mentioned in the comment on bugzilla, the first occurrence of "this is post_doc" is erroneous. This is happening because in argp-help.c in the function argp_doc 'char *vt' (which is responsible for determining the position for vertical tab in the doc string) is being initialized only once, It should be initialized for each child in the documentation. The next thing is the complete doc string needs to be printed only if 1. If there is only one child in the doc string and the doc string does not start with '\v'. 2. The argument 'first_only' to the function 'argp_doc' is 0. After applying the patch we get the output as following. $ argp-help --help Usage: argp-help [OPTION...] -?, --help Give this help list --usage Give a short usage message this is post_doc A test case for this is also added in the patch. Following is the patch for this bug. From 36cfdeab88ec3ecfe971cd70c798a9615d6adc41 Mon Sep 17 00:00:00 2001 From: Girish Joshi Date: Thu, 6 Feb 2020 01:03:18 +0530 Subject: [PATCH] Fix argp.doc prints incorrectly when it starts with '\v' (Bug 19038) "char *vt" in the function "argp_doc" is initialized for every child in the doc. The complete doc string is printed only in two cases. 1. There is only one child in the doc and the doc does not starts with '\v'. 2. Argument "first_only" to the function "argp_doc" is 0. Added test argp/tst-argp3.c for this case. --- argp/Makefile | 2 +- argp/argp-help.c | 10 +++++-- argp/tst-argp3.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 argp/tst-argp3.c + -- 2.21.1 diff --git a/argp/Makefile b/argp/Makefile index 1f9b074bed..0c0270ffef 100644 --- a/argp/Makefile +++ b/argp/Makefile @@ -27,7 +27,7 @@ routines = $(addprefix argp-, ba fmtstream fs-xinl help parse pv \ pvh xinl eexst) tests = argp-test tst-argp1 bug-argp1 tst-argp2 bug-argp2 \ - tst-ldbl-argp + tst-ldbl-argp tst-argp3 CFLAGS-argp-help.c += $(uses-callbacks) -fexceptions CFLAGS-argp-parse.c += $(uses-callbacks) diff --git a/argp/argp-help.c b/argp/argp-help.c index 2bcd6549fd..8d213e4586 100644 --- a/argp/argp-help.c +++ b/argp/argp-help.c @@ -1465,10 +1465,11 @@ argp_doc (const struct argp *argp, const struct argp_state *state, size_t inp_text_limit = 0; const char *doc = dgettext (argp->argp_domain, argp->doc); const struct argp_child *child = argp->children; + char *vt = 0; if (doc) { - char *vt = strchr (doc, '\v'); + vt = strchr (doc, '\v'); inp_text = post ? (vt ? vt + 1 : 0) : doc; inp_text_limit = (!post && vt) ? (vt - doc) : 0; } @@ -1499,7 +1500,12 @@ argp_doc (const struct argp *argp, const struct argp_state *state, if (text == inp_text && inp_text_limit) __argp_fmtstream_write (stream, inp_text, inp_text_limit); else - __argp_fmtstream_puts (stream, text); + { + if ((!vt && !child) || (text == inp_text && !first_only)) + { + __argp_fmtstream_puts (stream, text); + } + } if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream)) __argp_fmtstream_putc (stream, '\n'); diff --git a/argp/tst-argp3.c b/argp/tst-argp3.c new file mode 100644 index 0000000000..cfdace2574 --- /dev/null +++ b/argp/tst-argp3.c @@ -0,0 +1,68 @@ +/* Test for argparse with leading '\v' in the doc string. + Copyright (C) 2020 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see .*/ + + +#include +#include + +#include +#include + + +static char expected_success[] = "Usage: arp [OPTION...]\n\ +\n\ + -?, --help Give this help list\n\ + --usage Give a short usage message\n\ +\n\ +this is post_doc\n\ +"; +char *argv[3] = { (char *) "arp", NULL, NULL }; + +static void +do_test_call (void) +{ + static char doc[] = "\vthis is post_doc"; + static struct argp argp = {NULL, NULL, NULL, doc}; + + argp_parse (&argp, 2, argv, 0, 0, NULL); +} + +static int +do_one_test (const char *expected) +{ + struct support_capture_subprocess result; + result = support_capture_subprocess ((void *) &do_test_call, NULL); + + TEST_COMPARE_STRING (result.out.buffer, expected); + + return 0; +} + + +static int +do_test (void) +{ + const char *argument = "--help"; + argv[1] = (char *)argument; + // success condition + do_one_test (expected_success); + return 0; +} + +/* This file references do_test above and contains the definition of + the main function. */ +#include