[Mesa-dev] [PATCH v6 1/3] util: Add util_strlcpy
Gustaw Smolarczyk
wielkiegie at gmail.com
Thu Jul 6 19:05:51 UTC 2017
2017-07-06 20:52 GMT+02:00 Robert Foss <robert.foss at collabora.com>:
> On Wed, 2017-07-05 at 08:46 -0600, Brian Paul wrote:
>> On 07/05/2017 12:57 AM, Robert Foss wrote:
>> > Add local strlcpy implementation.
>> >
>> > Signed-off-by: Robert Foss <robert.foss at collabora.com>
>> > ---
>> > Changes since v5:
>> > Actually include changes from v5 in patch
>> >
>> > Changes since v4:
>> > Gustaw Smolarczyk <wielkiegie at gmail.com>
>> > - Make util_strlcpy have the same behaviour as strlcpy
>> >
>> > Changes since v3:
>> > Matt Turner <mattst88 at gmail.com>
>> > - Change name of util_strncpy to util_strlcpy
>> >
>> > Changes since v2:
>> > Brian Paul <brianp at vmware.com>
>> > - Patch added
>> >
>> >
>> > src/util/u_string.h | 9 +++++++++
>> > 1 file changed, 9 insertions(+)
>> >
>> > diff --git a/src/util/u_string.h b/src/util/u_string.h
>> > index e88e13f42c..bbabcbc7cb 100644
>> > --- a/src/util/u_string.h
>> > +++ b/src/util/u_string.h
>> > @@ -48,6 +48,15 @@
>> > extern "C" {
>> > #endif
>> >
>> > +static inline size_t
>> > +util_strlcpy(char *dst, const char *src, size_t n)
>> > +{
>> > + strncpy(dst, src, n);
>> > + dst[n-1] = '\0';
>> > +
>> > + return strnlen(src, n);
>> > +}
>>
>> This effectively walks over the source string twice. I'd suggest
>> just
>> using your own loop.
>>
>
> I don't think a solution can be built using strlen if we want to only
> iterate once. So one iteration will have to do both counting and
> copying, which rules out using memcpy too.
I would say that iterating twice should be fine since we also get to
use the optimized strlen and memcpy routines. Your open-coded version
doesn't vectorize nor unroll on gcc-7 -Ofast (as far as my simple
testing showed).
That said, performance of this function doesn't matter much - what
matters the most is ease of use and correctness.
>
> So how about something like this:
>
> static inline size_t
> util_strlcpy(char *dst, const char *src, size_t n)
> {
> size_t src_len = 0;
>
> /* Copy chars for as long as there is space in dst */
> while (src_len < (n - 1) && *src[src_len] != "\0") {
If n == 0, (n - 1) is the same as SIZE_MAX. I think you should check
for n == 0 and then just return strlen(src) before this loop is
entered. Or, alternatively, wrap the first loop and dst[src_len] =
'\0' assignment in if (n != 0) { ... }.
Also, use '\0' instead of "\0". And remove * before src[src_len].
> dst[src_len] = src[src_len];
> src_len++;
> }
>
> /* The last char of either src or if dst is filled
> * should always be \0.
> */
> dst[src_len] = '\0';
>
> /* Continue on finding the end of src */
> while (src[src_len] != "\0") {
Use '\0' instead of "\0".
> src_len++;
> }
>
> return src_len;
> }
>
> Rob.
Other than these, it looks correct.
Gustaw
More information about the mesa-dev
mailing list