git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Thomas Gummerer <t.gummerer@gmail.com>
To: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Cc: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>,
	git@vger.kernel.org
Subject: Re: [PATCH v11 03/22] strbuf.c: add `strbuf_insertf()` and `strbuf_vinsertf()`
Date: Tue, 27 Nov 2018 22:32:56 +0000	[thread overview]
Message-ID: <20181127223256.GM4883@hank.intra.tgummerer.com> (raw)
In-Reply-To: <nycvar.QRO.7.76.6.1811271428560.41@tvgsbejvaqbjf.bet>

On 11/27, Johannes Schindelin wrote:
> Hi,
> 
> On Sun, 25 Nov 2018, Thomas Gummerer wrote:
> 
> > On 11/23, Paul-Sebastian Ungureanu wrote:
> > > Implement `strbuf_insertf()` and `strbuf_vinsertf()` to
> > > insert data using a printf format string.
> > > 
> > > Original-idea-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> > > Signed-off-by: Paul-Sebastian Ungureanu <ungureanupaulsebastian@gmail.com>
> > > ---
> > >  strbuf.c | 36 ++++++++++++++++++++++++++++++++++++
> > >  strbuf.h |  9 +++++++++
> > >  2 files changed, 45 insertions(+)
> > > 
> > > diff --git a/strbuf.c b/strbuf.c
> > > index 82e90f1dfe..bfbbdadbf3 100644
> > > --- a/strbuf.c
> > > +++ b/strbuf.c
> > > @@ -249,6 +249,42 @@ void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len)
> > >  	strbuf_splice(sb, pos, 0, data, len);
> > >  }
> > >  
> > > +void strbuf_vinsertf(struct strbuf *sb, size_t pos, const char *fmt, va_list ap)
> > > +{
> > > +	int len, len2;
> > > +	char save;
> > > +	va_list cp;
> > > +
> > > +	if (pos > sb->len)
> > > +		die("`pos' is too far after the end of the buffer");
> > 
> > I was going to ask about translation of this and other messages in
> > 'die()' calls, but I see other messages in strbuf.c are not marked for
> > translation either.  It may make sense to mark them all for
> > translation at some point in the future, but having them all
> > untranslated for now makes sense.
> > 
> > In the long run it may even be better to return an error here rather
> > than 'die()'ing, but again this is consistent with the rest of the
> > API, so this wouldn't be a good time to take that on.
> 
> I guess I was too overzealous in my copying. These conditions really
> indicate bugs in the caller... So I'd actually rather change that die() to
> BUG().
> 
> But then, the original code in strbuf_vaddf() calls die() and would have
> to be changed, too.

Right, making these 'BUG()' makes sense to me.  But at this stage of
the series it's probably better to just aim for consistency with the
surrounding code without starting to do more cleanups that were not
included in earlier iterations.  I think that's best left for patches
on top.

> > > +	va_copy(cp, ap);
> > > +	len = vsnprintf(sb->buf + sb->len, 0, fmt, cp);
> > 
> > Here we're just getting the length of what we're trying to format
> > (excluding the final NUL).  As the second argument is 0, we do not
> > modify the strbuf at this point...
> > 
> > > +	va_end(cp);
> > > +	if (len < 0)
> > > +		BUG("your vsnprintf is broken (returned %d)", len);
> > > +	if (!len)
> > > +		return; /* nothing to do */
> > > +	if (unsigned_add_overflows(sb->len, len))
> > > +		die("you want to use way too much memory");
> > > +	strbuf_grow(sb, len);
> > 
> > ... and then we grow the strbuf by the length we previously, which
> > excludes the NUL character, plus one extra character, so even if pos
> > == len we are sure to have enough space in the strbuf ...
> > 
> > > +	memmove(sb->buf + pos + len, sb->buf + pos, sb->len - pos);
> > > +	/* vsnprintf() will append a NUL, overwriting one of our characters */
> > > +	save = sb->buf[pos + len];
> > > +	len2 = vsnprintf(sb->buf + pos, sb->alloc - sb->len, fmt, ap);
> > 
> > ... and we use vsnprintf to write the formatted string to the
> > beginning of the buffer.
> 
> It is not actually the beginning of the buffer, but possibly the middle of
> the buffer ;-)

Oops, you're right of course :) 

> > sb->alloc - sb->len can be larger than 'len', which is fine as vsnprintf
> > doesn't write anything after the NUL character.  And as 'strbuf_grow'
> > adds len + 1 bytes to the strbuf we'll always have enough space for
> > adding the formatted string ...
> > 
> > > +	sb->buf[pos + len] = save;
> > > +	if (len2 != len)
> > > +		BUG("your vsnprintf is broken (returns inconsistent lengths)");
> > > +	strbuf_setlen(sb, sb->len + len);
> > 
> > And finally we set the strbuf to the new length.  So all this is just
> > a very roundabout way to say that this function does the right thing
> > according to my reading (and tests).
> 
> :-)
> 
> It seems that Junio likes this way of reviewing, giving him confidence
> that the review was thorough.
>
> Thanks!
> Dscho
> 
> > > +}
> > > +
> > > +void strbuf_insertf(struct strbuf *sb, size_t pos, const char *fmt, ...)
> > > +{
> > > +	va_list ap;
> > > +	va_start(ap, fmt);
> > > +	strbuf_vinsertf(sb, pos, fmt, ap);
> > > +	va_end(ap);
> > > +}
> > > +
> > >  void strbuf_remove(struct strbuf *sb, size_t pos, size_t len)
> > >  {
> > >  	strbuf_splice(sb, pos, len, "", 0);
> > > diff --git a/strbuf.h b/strbuf.h
> > > index be02150df3..8f8fe01e68 100644
> > > --- a/strbuf.h
> > > +++ b/strbuf.h
> > > @@ -244,6 +244,15 @@ void strbuf_addchars(struct strbuf *sb, int c, size_t n);
> > >   */
> > >  void strbuf_insert(struct strbuf *sb, size_t pos, const void *, size_t);
> > >  
> > > +/**
> > > + * Insert data to the given position of the buffer giving a printf format
> > > + * string. The contents will be shifted, not overwritten.
> > > + */
> > > +void strbuf_vinsertf(struct strbuf *sb, size_t pos, const char *fmt,
> > > +		     va_list ap);
> > > +
> > > +void strbuf_insertf(struct strbuf *sb, size_t pos, const char *fmt, ...);
> > > +
> > >  /**
> > >   * Remove given amount of data from a given position of the buffer.
> > >   */
> > > -- 
> > > 2.19.1.878.g0482332a22
> > > 
> > 

  reply	other threads:[~2018-11-27 22:33 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <https://public-inbox.org/git/cover.1539553398.git.ungureanupaulsebastian@gmail.com/>
2018-11-22 23:05 ` [PATCH v11 00/22] Convert "git stash" to C builtin Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 01/22] sha1-name.c: add `get_oidf()` which acts like `get_oid()` Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 02/22] strbuf.c: add `strbuf_join_argv()` Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 03/22] strbuf.c: add `strbuf_insertf()` and `strbuf_vinsertf()` Paul-Sebastian Ungureanu
2018-11-25 21:43     ` Thomas Gummerer
2018-11-27 13:35       ` Johannes Schindelin
2018-11-27 22:32         ` Thomas Gummerer [this message]
2018-11-22 23:05   ` [PATCH v11 04/22] stash: improve option parsing test coverage Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 05/22] t3903: modernize style Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 06/22] stash: rename test cases to be more descriptive Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 07/22] stash: add tests for `git stash show` config Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 08/22] stash: mention options in `show` synopsis Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 09/22] stash: convert apply to builtin Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 10/22] stash: convert drop and clear " Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 11/22] stash: convert branch " Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 12/22] stash: convert pop " Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 13/22] stash: convert list " Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 14/22] stash: convert show " Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 15/22] stash: convert store " Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 16/22] stash: convert create " Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 17/22] stash: convert push " Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 18/22] stash: make push -q quiet Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 19/22] stash: convert save to builtin Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 20/22] stash: convert `stash--helper.c` into `stash.c` Paul-Sebastian Ungureanu
2018-11-26  5:30     ` Junio C Hamano
2018-11-27 13:46       ` Johannes Schindelin
2018-11-27 23:40         ` Ævar Arnfjörð Bjarmason
2018-11-29 10:58           ` Johannes Schindelin
2018-11-22 23:05   ` [PATCH v11 21/22] stash: optimize `get_untracked_files()` and `check_changes()` Paul-Sebastian Ungureanu
2018-11-22 23:05   ` [PATCH v11 22/22] stash: replace all `write-tree` child processes with API calls Paul-Sebastian Ungureanu
2018-11-25 21:55   ` [PATCH v11 00/22] Convert "git stash" to C builtin Thomas Gummerer
2018-11-26  5:47     ` Junio C Hamano
2018-11-26  7:38       ` Junio C Hamano
2018-11-29 12:54         ` Johannes Schindelin
2018-11-29 14:06           ` Johannes Schindelin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181127223256.GM4883@hank.intra.tgummerer.com \
    --to=t.gummerer@gmail.com \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=ungureanupaulsebastian@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).