jdict

command line tool for looking up terms in yomidict dictionaries
git clone anongit@rnpnr.xyz:jdict.git
Log | Files | Refs | Feed | README | LICENSE

Commit: f2489e0990363abb3b0ac20324d7b76e8367c9c0
Parent: f6b42c53006b3a70b513f77be8a5f94c9594167b
Author: Randy Palamar
Date:   Sat, 28 Oct 2023 22:05:31 -0600

replace strndup with wrapper around memcpy

The length of the copied region is known so there is no reason for
strndup() to scan for NUL. This gives a little performance boost:

New [clang -O3]: avgtime -n 128 ./jdict -d koujien 驀進
real 0.567266
user 0.431016
sys 0.123359

old [clang -O3]: avgtime -n 128 ./jdict -d koujien 驀進
real 0.588203
user 0.454063
sys 0.122734

Not that it matters in this case but xmemdup() is also checks for
errors as opposed to blindly assuming strndup() didn't return NULL.

Diffstat:
Mjdict.c | 7++++---
Mutil.c | 12++++++++++++
Mutil.h | 1+
3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/jdict.c b/jdict.c @@ -2,6 +2,7 @@ #include <dirent.h> #include <fcntl.h> #include <limits.h> +#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -124,12 +125,12 @@ make_ent(YomiTok *toks, char *data) return NULL; d = xreallocarray(NULL, 1, sizeof(DictEnt)); - d->term = strndup(data + tstr->start, tstr->end - tstr->start); + d->term = xmemdup(data + tstr->start, tstr->end - tstr->start); d->ndefs = tdefs->len; d->defs = xreallocarray(NULL, d->ndefs, sizeof(char *)); for (i = 1; i <= d->ndefs; i++) - d->defs[i-1] = strndup(data + tdefs[i].start, - tdefs[i].end - tdefs[i].start); + d->defs[i - 1] = xmemdup(data + tdefs[i].start, + tdefs[i].end - tdefs[i].start); return d; } diff --git a/util.c b/util.c @@ -1,6 +1,7 @@ /* See LICENSE for license details. */ #include <ctype.h> #include <stdarg.h> +#include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -59,3 +60,14 @@ xreallocarray(void *o, size_t n, size_t s) return new; } + +char * +xmemdup(void *src, ptrdiff_t len) +{ + char *p; + if (len < 0) + die("xmemdup(): negative len\n"); + p = xreallocarray(NULL, 1, len); + p[len] = 0; + return memcpy(p, src, len); +} diff --git a/util.h b/util.h @@ -4,4 +4,5 @@ void die(const char *, ...); char *fix_newlines(char *); char *trim(char *); +char *xmemdup(void *, ptrdiff_t); void *xreallocarray(void *, size_t, size_t);