mkdep: avoid memory allocation in findcc
This change takes the idea of handling strings as pairs in the form (start, len) by Robert Elz from https://mail-index.netbsd.org/source-changes-d/2021/08/20/msg013427.html and expands it by avoiding one more memory allocation, for iterating the PATH environment variable. No functional change.
This commit is contained in:
parent
9108d0c35f
commit
1c89b83dd4
|
@ -1,4 +1,4 @@
|
||||||
# $NetBSD: Makefile,v 1.2 2021/08/11 20:42:26 rillig Exp $
|
# $NetBSD: Makefile,v 1.3 2021/08/20 06:36:10 rillig Exp $
|
||||||
|
|
||||||
.include <bsd.own.mk>
|
.include <bsd.own.mk>
|
||||||
|
|
||||||
|
@ -13,5 +13,6 @@ PROG= h_findcc
|
||||||
SRCS= h_findcc.c findcc.c
|
SRCS= h_findcc.c findcc.c
|
||||||
CPPFLAGS+= -I${NETBSDSRCDIR}/usr.bin/mkdep
|
CPPFLAGS+= -I${NETBSDSRCDIR}/usr.bin/mkdep
|
||||||
MAN.h_findcc= # none
|
MAN.h_findcc= # none
|
||||||
|
WARNS= 6
|
||||||
|
|
||||||
.include <bsd.test.mk>
|
.include <bsd.test.mk>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $NetBSD: t_findcc.sh,v 1.2 2021/08/20 05:45:19 rillig Exp $
|
# $NetBSD: t_findcc.sh,v 1.3 2021/08/20 06:36:10 rillig Exp $
|
||||||
#
|
#
|
||||||
# Copyright (c) 2021 The NetBSD Foundation, Inc.
|
# Copyright (c) 2021 The NetBSD Foundation, Inc.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
@ -51,6 +51,31 @@ base_found_body() {
|
||||||
"$(atf_get_srcdir)"/h_findcc 'echo'
|
"$(atf_get_srcdir)"/h_findcc 'echo'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# A plain program name is searched in the PATH and, in this example, it is
|
||||||
|
# found in '/bin', which comes second in the PATH.
|
||||||
|
#
|
||||||
|
atf_test_case base_found_second
|
||||||
|
base_found_second_body() {
|
||||||
|
atf_check -o "inline:/bin/echo$n" \
|
||||||
|
env -i PATH='/nonexistent:/bin' \
|
||||||
|
"$(atf_get_srcdir)"/h_findcc 'echo'
|
||||||
|
}
|
||||||
|
|
||||||
|
# A plain program name is searched in the PATH and, in this example, it is
|
||||||
|
# found in './bin', a relative path in the PATH, which is rather unusual in
|
||||||
|
# practice.
|
||||||
|
#
|
||||||
|
atf_test_case base_found_reldir
|
||||||
|
base_found_reldir_body() {
|
||||||
|
mkdir bin
|
||||||
|
echo '#! /bin/sh' > 'bin/reldir-echo'
|
||||||
|
chmod +x 'bin/reldir-echo'
|
||||||
|
|
||||||
|
atf_check -o "inline:bin/reldir-echo$n" \
|
||||||
|
env -i PATH='/nonexistent:bin' \
|
||||||
|
"$(atf_get_srcdir)"/h_findcc 'reldir-echo'
|
||||||
|
}
|
||||||
|
|
||||||
# The C compiler can be specified as a program with one or more arguments.
|
# The C compiler can be specified as a program with one or more arguments.
|
||||||
# If the program name is a plain name without any slash, the argument is
|
# If the program name is a plain name without any slash, the argument is
|
||||||
# discarded.
|
# discarded.
|
||||||
|
@ -143,6 +168,8 @@ abs_arg_found_body() {
|
||||||
atf_init_test_cases() {
|
atf_init_test_cases() {
|
||||||
atf_add_test_case base_not_found
|
atf_add_test_case base_not_found
|
||||||
atf_add_test_case base_found
|
atf_add_test_case base_found
|
||||||
|
atf_add_test_case base_found_second
|
||||||
|
atf_add_test_case base_found_reldir
|
||||||
atf_add_test_case base_arg_found
|
atf_add_test_case base_arg_found
|
||||||
|
|
||||||
atf_add_test_case rel_not_found
|
atf_add_test_case rel_not_found
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: findcc.c,v 1.9 2021/08/20 05:45:19 rillig Exp $ */
|
/* $NetBSD: findcc.c,v 1.10 2021/08/20 06:36:10 rillig Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#if !defined(lint)
|
#if !defined(lint)
|
||||||
__COPYRIGHT("@(#) Copyright (c) 1999 The NetBSD Foundation, Inc.\
|
__COPYRIGHT("@(#) Copyright (c) 1999 The NetBSD Foundation, Inc.\
|
||||||
All rights reserved.");
|
All rights reserved.");
|
||||||
__RCSID("$NetBSD: findcc.c,v 1.9 2021/08/20 05:45:19 rillig Exp $");
|
__RCSID("$NetBSD: findcc.c,v 1.10 2021/08/20 06:36:10 rillig Exp $");
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -49,47 +49,40 @@ __RCSID("$NetBSD: findcc.c,v 1.9 2021/08/20 05:45:19 rillig Exp $");
|
||||||
#include "findcc.h"
|
#include "findcc.h"
|
||||||
|
|
||||||
char *
|
char *
|
||||||
findcc(const char *cc_command)
|
findcc(const char *progname)
|
||||||
{
|
{
|
||||||
char *progname, *path, *dir, *next;
|
char *cc;
|
||||||
char buffer[MAXPATHLEN];
|
const char *path, *dir;
|
||||||
|
char buffer[MAXPATHLEN];
|
||||||
|
size_t progname_len, dir_len;
|
||||||
|
|
||||||
if ((progname = strdup(cc_command)) == NULL)
|
progname_len = strcspn(progname, " ");
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ((next = strchr(progname, ' ')) != NULL)
|
if (memchr(progname, '/', progname_len) != NULL) {
|
||||||
*next = '\0';
|
if ((cc = strndup(progname, progname_len)) == NULL)
|
||||||
|
return NULL;
|
||||||
if (strchr(progname, '/') != NULL) {
|
if (access(cc, X_OK) == 0)
|
||||||
if (access(progname, X_OK) == 0)
|
return cc;
|
||||||
return progname;
|
free(cc);
|
||||||
free(progname);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((path = getenv("PATH")) == NULL) ||
|
if ((path = getenv("PATH")) == NULL)
|
||||||
((path = strdup(path)) == NULL)) {
|
|
||||||
free(progname);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
for (dir = path; *dir != '\0'; ) {
|
||||||
|
dir_len = strcspn(dir, ":");
|
||||||
|
|
||||||
|
if ((size_t)snprintf(buffer, sizeof(buffer), "%.*s/%.*s",
|
||||||
|
(int)dir_len, dir, (int)progname_len, progname)
|
||||||
|
< sizeof(buffer)
|
||||||
|
&& access(buffer, X_OK) == 0)
|
||||||
|
return strdup(buffer);
|
||||||
|
|
||||||
|
dir += dir_len;
|
||||||
|
if (*dir == ':')
|
||||||
|
dir++;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = path;
|
|
||||||
while (dir != NULL) {
|
|
||||||
if ((next = strchr(dir, ':')) != NULL)
|
|
||||||
*next++ = '\0';
|
|
||||||
|
|
||||||
if (snprintf(buffer, sizeof(buffer),
|
|
||||||
"%s/%s", dir, progname) < (int)sizeof(buffer)) {
|
|
||||||
if (access(buffer, X_OK) == 0) {
|
|
||||||
free(path);
|
|
||||||
free(progname);
|
|
||||||
return strdup(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dir = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(path);
|
|
||||||
free(progname);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue