summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormuffin <none@none>2005-11-23 12:27:47 -0800
committermuffin <none@none>2005-11-23 12:27:47 -0800
commit55381082fdea0647bb5d44ceeed7d5af386f30d2 (patch)
tree8e6851940bfff2b264e5ed1aae9203658003f7ff
parent1a48003f96d5bf304ca739198913e42e5adb9bcf (diff)
downloadillumos-joyent-55381082fdea0647bb5d44ceeed7d5af386f30d2.tar.gz
6210677 dirname and basename are slower than they should be
--HG-- rename : usr/src/cmd/basename/basename.sh => deleted_files/usr/src/cmd/basename/basename.sh rename : usr/src/cmd/dirname/dirname.sh => deleted_files/usr/src/cmd/dirname/dirname.sh
-rw-r--r--deleted_files/usr/src/cmd/basename/basename.sh (renamed from usr/src/cmd/basename/basename.sh)0
-rw-r--r--deleted_files/usr/src/cmd/dirname/dirname.sh (renamed from usr/src/cmd/dirname/dirname.sh)0
-rw-r--r--usr/src/Makefile.lint1
-rw-r--r--usr/src/cmd/basename/Makefile17
-rw-r--r--usr/src/cmd/basename/basename.c145
-rw-r--r--usr/src/cmd/dirname/Makefile7
-rw-r--r--usr/src/cmd/dirname/dirname.c108
7 files changed, 222 insertions, 56 deletions
diff --git a/usr/src/cmd/basename/basename.sh b/deleted_files/usr/src/cmd/basename/basename.sh
index 2c7249f007..2c7249f007 100644
--- a/usr/src/cmd/basename/basename.sh
+++ b/deleted_files/usr/src/cmd/basename/basename.sh
diff --git a/usr/src/cmd/dirname/dirname.sh b/deleted_files/usr/src/cmd/dirname/dirname.sh
index d3cc0928f6..d3cc0928f6 100644
--- a/usr/src/cmd/dirname/dirname.sh
+++ b/deleted_files/usr/src/cmd/dirname/dirname.sh
diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint
index d7e724c006..9f650e4a01 100644
--- a/usr/src/Makefile.lint
+++ b/usr/src/Makefile.lint
@@ -103,6 +103,7 @@ COMMON_SUBDIRS = \
cmd/devmgmt \
cmd/dfs.cmds \
cmd/diff3 \
+ cmd/dirname \
cmd/diskscan \
cmd/dispadmin \
cmd/dladm \
diff --git a/usr/src/cmd/basename/Makefile b/usr/src/cmd/basename/Makefile
index f6da64048b..e29b1b6220 100644
--- a/usr/src/cmd/basename/Makefile
+++ b/usr/src/cmd/basename/Makefile
@@ -22,32 +22,29 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
PROG= basename
XPG4PROG= basename
-SRCS= $(PROG:%=%.sh)
-
include ../Makefile.cmd
-$(XPG4) := CFLAGS += $(CCVERBOSE)
+$(XPG4) := CFLAGS += -DXPG4 $(CCVERBOSE)
+lint_PROG_XPG4 := CPPFLAGS += -DXPG4
.KEEP_STATE:
all: $(PROG) $(XPG4)
-$(PROG): $(PROG).sh
- $(RM) $@
- cat $(PROG).sh > $@
- chmod +x $@
-
install: all $(ROOTPROG) $(ROOTXPG4PROG)
clean:
-lint: lint_PROG
+lint: lint_PROG lint_PROG_XPG4
+
+lint_PROG_XPG4: $(PROG).c
+ $(LINT.c) $(PROG).c $(LDLIBS)
include ../Makefile.targ
diff --git a/usr/src/cmd/basename/basename.c b/usr/src/cmd/basename/basename.c
index c4d3fbb733..af4026a488 100644
--- a/usr/src/cmd/basename/basename.c
+++ b/usr/src/cmd/basename/basename.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,9 +30,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
-static void output(char *);
-static void usage(void);
+#ifndef XPG4
+#include <unistd.h>
+#include <regex.h>
+#include <libintl.h>
+#endif
int
main(int argc, char **argv)
@@ -40,71 +42,130 @@ main(int argc, char **argv)
char *p;
char *string;
char *suffix;
+#ifndef XPG4
+ int r;
+ char suf_buf[256];
+ char *suf_pat;
+ size_t suf_len;
+ regex_t reg;
+ regmatch_t pmatch[2];
+#endif
- (void) setlocale(LC_ALL, "");
+ /*
+ * For better performance, defer the setlocale()/textdomain()
+ * calls until they get really required.
+ */
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
- (void) textdomain(TEXT_DOMAIN);
-
- if (argc == 1)
- output(".");
+ if (argc == 1) {
+ (void) puts(".");
+ return (0);
+ }
+#ifdef XPG4
if (strcmp(argv[1], "--") == 0) {
argv++;
argc--;
+ if (argc == 1) {
+ (void) puts(".");
+ return (0);
+ }
+ }
+#endif
+ if (argc > 3) {
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+ (void) fputs(gettext("Usage: basename string [ suffix ]\n"),
+ stderr);
+ return (1);
}
-
- if (argc == 1)
- output(".");
-
- if (argc > 3)
- usage();
string = argv[1];
suffix = (argc == 2) ? NULL : argv[2];
- if (*string == '\0')
- output(".");
+ if (*string == '\0') {
+ (void) puts(".");
+ return (0);
+ }
/* remove trailing slashes */
- p = string + strlen(string) -1;
- while ((p >= string) && (*p == '/'))
+ p = string + strlen(string) - 1;
+ while (p >= string && *p == '/')
*p-- = '\0';
- if (*string == '\0')
- output("/");
+ if (*string == '\0') {
+ (void) puts("/");
+ return (0);
+ }
/* skip to one past last slash */
if ((p = strrchr(string, '/')) != NULL)
string = p + 1;
+ if (suffix == NULL) {
+ (void) puts(string);
+ return (0);
+ }
+
+#ifdef XPG4
/*
* if a suffix is present and is not the same as the remaining
* string and is identical to the last characters in the remaining
* string, remove those characters from the string.
*/
- if (suffix != NULL)
- if (strcmp(string, suffix) != NULL) {
- p = string + strlen(string) - strlen(suffix);
- if (strcmp(p, suffix) == NULL)
- *p = '\0';
- }
-
- output(string);
+ if (strcmp(string, suffix) != 0) {
+ p = string + strlen(string) - strlen(suffix);
+ if (strcmp(p, suffix) == 0)
+ *p = '\0';
+ }
+ (void) puts(string);
return (0);
-}
-
-static void
-output(char *string)
-{
- (void) printf("%s\n", string);
- exit(0);
-}
+#else
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
-static void usage(void)
-{
- (void) fprintf(stderr,
- gettext("Usage: basename string [ suffix ]\n"));
- exit(1);
+ suf_len = 6 + strlen(suffix) + 1 + 1; /* \(.*\)suffix$ */
+ if (suf_len > sizeof (suf_buf)) {
+ suf_pat = malloc(suf_len);
+ if (suf_pat == NULL) {
+ (void) fputs("malloc failed\n", stderr);
+ return (1);
+ }
+ } else {
+ suf_pat = suf_buf;
+ }
+ (void) strcpy(suf_pat, "\\(.*\\)");
+ (void) strcpy(suf_pat + 6, suffix);
+ *(suf_pat + suf_len - 1 - 1) = '$';
+ *(suf_pat + suf_len - 1) = '\0';
+
+ r = regcomp(&reg, suf_pat, 0);
+ if (r != 0) {
+ (void) fprintf(stderr,
+ "Internal error: regcomp failed for \"%s\"\n",
+ suf_pat);
+ return (1);
+ }
+ r = regexec(&reg, string, 2, pmatch, 0);
+ if (r == 0) {
+ if (pmatch[0].rm_so == (regoff_t)-1 ||
+ pmatch[1].rm_so == (regoff_t)-1 ||
+ pmatch[1].rm_so != 0) {
+ (void) fprintf(stderr, "Internal error: regexec did "
+ "not set sub-expression for:\n");
+ (void) fprintf(stderr, "path: \"%s\"\n", string);
+ (void) fprintf(stderr, "pattern: \"%s\"", suf_pat);
+ return (1);
+ }
+ if (pmatch[1].rm_so == pmatch[1].rm_eo) {
+ /* a null string matched */
+ (void) printf("%s\n", string);
+ return (0);
+ }
+ string[pmatch[1].rm_eo] = '\0';
+ }
+ (void) puts(string);
+ return (0);
+#endif
}
diff --git a/usr/src/cmd/dirname/Makefile b/usr/src/cmd/dirname/Makefile
index 14ff338b02..c4fd585cb9 100644
--- a/usr/src/cmd/dirname/Makefile
+++ b/usr/src/cmd/dirname/Makefile
@@ -22,13 +22,12 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright (c) 1989 by Sun Microsystems, Inc.
+# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
#
PROG= dirname
-SRCS= $(PROG:%=%.sh)
-
include ../Makefile.cmd
.KEEP_STATE:
@@ -39,6 +38,6 @@ install: all $(ROOTPROG)
clean:
-lint:
+lint: lint_PROG
include ../Makefile.targ
diff --git a/usr/src/cmd/dirname/dirname.c b/usr/src/cmd/dirname/dirname.c
new file mode 100644
index 0000000000..6a07801ea2
--- /dev/null
+++ b/usr/src/cmd/dirname/dirname.c
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <libintl.h>
+
+int
+main(int argc, char **argv)
+{
+ char *p;
+ char *string;
+
+ /*
+ * For better performance, defer the setlocale()/textdomain()
+ * calls until they get really required.
+ */
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SYS_TEST"
+#endif
+ if (argc == 1) {
+ (void) puts(".");
+ return (0);
+ }
+ if (strcmp(argv[1], "--") == 0) {
+ argv++;
+ argc--;
+ if (argc == 1) {
+ (void) puts(".");
+ return (0);
+ }
+ }
+ if (argc > 2) {
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+ (void) fprintf(stderr, gettext("Usage: dirname [ path ]\n"));
+ return (1);
+ }
+
+ string = argv[1];
+
+ if (*string == '\0') {
+ (void) puts(".");
+ return (0);
+ }
+
+ /* remove trailing slashes */
+ p = string + strlen(string) - 1;
+ while (p >= string && *p == '/')
+ *p-- = '\0';
+
+ if (*string == '\0') {
+ /* string contained only slashes */
+ (void) puts("/");
+ return (0);
+ }
+
+ /* remove non-slashes */
+ while (p >= string && *p != '/')
+ *p-- = '\0';
+
+ if (*string == '\0') {
+ /* string did not begin with a slash */
+ (void) puts(".");
+ return (0);
+ }
+
+ /* remove slashes delimiting dirname and basename */
+ while (p >= string && *p == '/')
+ *p-- = '\0';
+
+ if (*string == '\0') {
+ /* no dirname part found */
+ (void) puts("/");
+ return (0);
+ }
+ /* now string points to dirname part */
+ (void) puts(string);
+ return (0);
+}