sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

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:
MMakefile | 2+-
Aarg.h | 31+++++++++++++++++++++++++++++++
Mbasename.1 | 15+++++++++++++++
Mbasename.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; } +