basename.c (2238B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include <libgen.h> // basename
- #include <stdbool.h>
- #include <stdio.h> // puts, perror
- #include <string.h> // strlen, strncmp
- #include <unistd.h> // getopt
- const char *argv0 = "basename";
- #ifdef __GNUC__
- #define _NonNull __attribute__((nonnull))
- #else
- #define _NonNull
- #endif
- _NonNull static char *
- suffix_basename(char *name, char *suffix)
- {
- char *string = basename(name);
- size_t suflen = strlen(suffix);
- size_t len = strlen(string);
- if(suflen < len && strcmp(&string[len - suflen], suffix) == 0)
- {
- string[len - suflen] = '\0';
- }
- return string;
- }
- static void
- usage()
- {
- fputs("Usage: basename [-z] [path] [suffix]\n"
- " basename [-az] [-s suffix] [path...]\n",
- stderr);
- }
- int
- main(int argc, char *argv[])
- {
- bool opt_a = false;
- char *suffix = NULL;
- char delim = '\n';
- int c = -1;
- while((c = getopt(argc, argv, ":as:z")) != -1)
- {
- switch(c)
- {
- case 'a':
- opt_a = true;
- break;
- case 's':
- opt_a = true;
- suffix = optarg;
- break;
- case 'z':
- delim = '\0';
- break;
- case ':':
- fprintf(stderr, "%s: error: Missing operand for option '-%c'\n", argv0, optopt);
- usage();
- return 1;
- case '?':
- fprintf(stderr, "%s: error: Unrecognised option '-%c'\n", argv0, optopt);
- usage();
- return 1;
- }
- }
- argc -= optind;
- argv += optind;
- if(!opt_a || argc == 0)
- {
- int ret = 0;
- switch(argc)
- {
- case 0:
- ret = printf(".%c", delim);
- break;
- case 1:
- ret = printf("%s%c", basename(argv[0]), delim);
- break;
- case 2:
- ret = printf("%s%c", suffix_basename(argv[0], argv[1]), delim);
- break;
- default:
- usage();
- return 1;
- }
- if(ret < 0)
- {
- perror("basename: error: Failed to print result");
- return 1;
- }
- return 0;
- }
- for(int argi = 0; argi < argc; argi++)
- {
- char *res = NULL;
- if(suffix != NULL)
- res = suffix_basename(argv[argi], suffix);
- else
- res = basename(argv[argi]);
- if(printf("%s%c", res, delim) < 0)
- {
- perror("basename: error: Failed to print result");
- return 1;
- }
- }
- return 0;
- }