git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
To: Thomas Gummerer <t.gummerer@gmail.com>
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 14:35:30 +0100 (STD)	[thread overview]
Message-ID: <nycvar.QRO.7.76.6.1811271428560.41@tvgsbejvaqbjf.bet> (raw)
In-Reply-To: <20181125214353.GI4883@hank.intra.tgummerer.com>

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.

> > +	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 ;-)

> 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 13:35 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 [this message]
2018-11-27 22:32         ` Thomas Gummerer
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=nycvar.QRO.7.76.6.1811271428560.41@tvgsbejvaqbjf.bet \
    --to=johannes.schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=t.gummerer@gmail.com \
    --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).