commit f75d7a47ff1058e45c89b39b60c41c933ab959f5
parent 96b15a5afa6ef6d4e2737aec8f9bbf838b3aa632
Author: Christoph Lohmann <20h@r-36.net>
Date: Mon, 23 Apr 2012 15:50:47 +0200
Adding ARGBEGIN for basename.
Diffstat:
M | Makefile | | | 2 | +- |
A | arg.h | | | 31 | +++++++++++++++++++++++++++++++ |
M | basename.1 | | | 15 | +++++++++++++++ |
M | basename.c | | | 66 | ++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- |
4 files changed, 99 insertions(+), 15 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
include config.mk
-HDR = fs.h text.h util.h
+HDR = fs.h text.h util.h arg.h
LIB = \
util/afgets.o \
util/agetcwd.o \
diff --git a/arg.h b/arg.h
@@ -0,0 +1,31 @@
+extern char *argv0;
+
+#define USED(x) ((void)(x))
+
+#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
+ argv[0] && argv[0][1]\
+ && argv[0][0] == '-';\
+ argc--, argv++) {\
+ char _argc;\
+ char **_argv;\
+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\
+ argv++;\
+ argc--;\
+ break;\
+ }\
+ for (argv[0]++, _argv = argv; argv[0][0];\
+ argv[0]++) {\
+ if (_argv != argv)\
+ break;\
+ _argc = argv[0][0];\
+ switch (_argc)
+
+#define ARGEND }\
+ USED(_argc);\
+ }\
+ USED(argv);\
+ USED(argc);
+
+#define EARGF(x) ((argv[1] == NULL)? ((x), abort(), (char *)0) :\
+ (argc--, argv++, argv[0]))
+
diff --git a/basename.1 b/basename.1
@@ -3,6 +3,10 @@
basename \- strip leading path component
.SH SYNOPSIS
.B basename
+.RB [ \-a ]
+.RB [ \-z ]
+.RB [ \-s
+.IR suffix ]
.I string
.RI [ suffix ]
.SH DESCRIPTION
@@ -12,6 +16,17 @@ prints the
with any leading path components, and the
.IR suffix ,
removed.
+.SH OPTIONS
+.TP
+.BI \-a
+multiple arguments will each be treated as strings
+.TP
+.BI \-s " suffix"
+specifies the suffix that should be removed
+.TP
+.BI \-z
+output will be separated with NUL
+.TP
.SH SEE ALSO
.IR dirname (1),
.IR basename (3)
diff --git a/basename.c b/basename.c
@@ -4,25 +4,63 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <stdbool.h>
+
+#include "arg.h"
#include "util.h"
+char *argv0;
+
+void
+usage(void)
+{
+ eprintf("usage: %s [-ahz] [-s suffix] name [suffix]\n",
+ basename(argv0));
+}
+
int
main(int argc, char *argv[])
{
- char *s;
- size_t n;
-
- if(getopt(argc, argv, "") != -1)
- exit(EXIT_FAILURE);
- if(optind == argc)
- eprintf("usage: %s string [suffix]\n", argv[0]);
-
- s = basename(argv[optind++]);
- if(optind < argc && strlen(s) > strlen(argv[optind])) {
- n = strlen(s) - strlen(argv[optind]);
- if(!strcmp(&s[n], argv[optind]))
- s[n] = '\0';
+ char *s, *suffix = NULL;
+ size_t n, sn;
+ bool aflag = false, zflag = false;
+
+ ARGBEGIN {
+ case 'a':
+ aflag = true;
+ break;
+ case 's':
+ suffix = EARGF(usage());
+ break;
+ case 'z':
+ zflag = true;
+ break;
+ case 'h':
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc < 1)
+ usage();
+
+ if (!aflag && argc == 2)
+ suffix = argv[1];
+ if (suffix)
+ sn = strlen(suffix);
+
+ for (; argc > 0; argc--, argv++) {
+ s = basename(argv[0]);
+ if (suffix) {
+ n = strlen(s) - sn;
+ if (!strcmp(&s[n], suffix))
+ s[n] = '\0';
+ }
+ printf("%s%c", s, (zflag)? '\0' : '\n');
+
+ if (!aflag)
+ break;
}
- puts(s);
+
return EXIT_SUCCESS;
}
+