diff --git a/misc.h b/misc.h index a6f9da40..a8eb7a19 100644 --- a/misc.h +++ b/misc.h @@ -168,8 +168,14 @@ static inline ptrlen ptrlen_from_strbuf(strbuf *sb) bool ptrlen_eq_string(ptrlen pl, const char *str); bool ptrlen_eq_ptrlen(ptrlen pl1, ptrlen pl2); int ptrlen_strcmp(ptrlen pl1, ptrlen pl2); +/* ptrlen_startswith and ptrlen_endswith write through their 'tail' + * argument if and only if it is non-NULL and they return true. Hence + * you can write ptrlen_startswith(thing, prefix, &thing), writing + * back to the same ptrlen it read from, to remove a prefix if present + * and say whether it did so. */ bool ptrlen_startswith(ptrlen whole, ptrlen prefix, ptrlen *tail); bool ptrlen_endswith(ptrlen whole, ptrlen suffix, ptrlen *tail); +ptrlen ptrlen_get_word(ptrlen *input, const char *separators); char *mkstr(ptrlen pl); int string_length_for_printf(size_t); /* Derive two printf arguments from a ptrlen, suitable for "%.*s" */ diff --git a/utils.c b/utils.c index 96024d2f..168a4a4f 100644 --- a/utils.c +++ b/utils.c @@ -938,6 +938,26 @@ bool ptrlen_endswith(ptrlen whole, ptrlen suffix, ptrlen *tail) return false; } +ptrlen ptrlen_get_word(ptrlen *input, const char *separators) +{ + const char *p = input->ptr, *end = p + input->len; + ptrlen toret; + + while (p < end && strchr(separators, *p)) + p++; + toret.ptr = p; + while (p < end && !strchr(separators, *p)) + p++; + toret.len = p - (const char *)toret.ptr; + + size_t to_consume = p - (const char *)input->ptr; + assert(to_consume <= input->len); + input->ptr = (const char *)input->ptr + to_consume; + input->len -= to_consume; + + return toret; +} + char *mkstr(ptrlen pl) { char *p = snewn(pl.len + 1, char);