Skip to content

Commit 35480f0

Browse files
peffgitster
authored andcommitted
add strip_suffix function
Many callers of ends_with want to not only find out whether a string has a suffix, but want to also strip it off. Doing that separately has two minor problems: 1. We often run over the string twice (once to find the suffix, and then once more to find its length to subtract the suffix length). 2. We have to specify the suffix length again, which means either a magic number, or repeating ourselves with strlen("suffix"). Just as we have skip_prefix to avoid these cases with starts_with, we can add a strip_suffix to avoid them with ends_with. Note that we add two forms of strip_suffix here: one that takes a string, with the resulting length as an out-parameter; and one that takes a pointer/length pair, and reuses the length as an out-parameter. The latter is more efficient when the caller already has the length (e.g., when using strbufs), but it can be easy to confuse the two, as they take the same number and types of parameters. For that reason, the "mem" form puts its length parameter next to the buffer (since they are a pair), and the string form puts it at the end (since it is an out-parameter). The compiler can notice when you get the order wrong, which should help prevent writing one when you meant the other. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 880fb8d commit 35480f0

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

git-compat-util.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,33 @@ static inline const char *skip_prefix(const char *str, const char *prefix)
350350
return NULL;
351351
}
352352

353+
/*
354+
* If buf ends with suffix, return 1 and subtract the length of the suffix
355+
* from *len. Otherwise, return 0 and leave *len untouched.
356+
*/
357+
static inline int strip_suffix_mem(const char *buf, size_t *len,
358+
const char *suffix)
359+
{
360+
size_t suflen = strlen(suffix);
361+
if (*len < suflen || memcmp(buf + (*len - suflen), suffix, suflen))
362+
return 0;
363+
*len -= suflen;
364+
return 1;
365+
}
366+
367+
/*
368+
* If str ends with suffix, return 1 and set *len to the size of the string
369+
* without the suffix. Otherwise, return 0 and set *len to the size of the
370+
* string.
371+
*
372+
* Note that we do _not_ NUL-terminate str to the new length.
373+
*/
374+
static inline int strip_suffix(const char *str, const char *suffix, size_t *len)
375+
{
376+
*len = strlen(str);
377+
return strip_suffix_mem(str, len, suffix);
378+
}
379+
353380
#if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
354381

355382
#ifndef PROT_READ

0 commit comments

Comments
 (0)