Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation for basename #49

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ src/rmdir/rmdir
src/sh/sh
src/sleep/sleep
src/cksum/cksum
src/basename/basename

bin/

Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ BINS += chmod
BINS += sh
BINS += sleep
BINS += cksum
BINS += basename

BINARIES := $(foreach b, $(BINS), src/$b/$b)
BINS-COPY := $(foreach b, $(BINS), bin/$b)
Expand Down
5 changes: 5 additions & 0 deletions src/basename/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
OUT := basename

SRC := basename.c

include ../shared.mk
1 change: 1 addition & 0 deletions src/basename/basename.1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
\" TODO
106 changes: 106 additions & 0 deletions src/basename/basename.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAME "basename (canoutils)"
#define VERSION "0.0.1"
#define AUTHOR "cospplredman"

#include "cgetopt.h"
#include "version_info.h"

static const char usage[] = {"Usage: basename [Options]... NAMES [suffix]\n"
" --version version information\n"
" --help display this help and exit\n"
" -z print zero instead of newline\n"
" -a multiple NAMES and no suffix\n"};

// flags
static int print_zero = 0;
static int multiple = 0;

static struct option long_options[] = {
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
};

static char *basename(char *str, char *suffix) {
char *end = str + strlen(str), *start = str;

/* remove trailing '/' */
for (; --end > start && *end == '/';)
*end = 0;

/* remove prefix ending with '/' */
for (; start < end; start++)
if (*start == '/')
str = start + 1;

/* remove suffix */
size_t sufflen = strlen(suffix);
if (end + 1 - sufflen >= str && strcmp(suffix, end + 1 - sufflen) == 0)
*(end + 1 - sufflen) = 0;

return str;
}

int main(int argc, char **argv) {
int opt, option_index;
while ((opt = getopt_long(argc, argv, "za", long_options, &option_index)) !=
-1) {
switch (opt) {
case 0:
break;
case 'v':
print_version();
return EXIT_SUCCESS;
break;
case 'h':
printf("%s\n", usage);
return EXIT_SUCCESS;
case 'z':
print_zero = 1;
break;
case 'a':
multiple = 1;
break;
}
}

argc -= optind;
argv += optind;

if (argc < 1 || (!multiple && argc > 2)) {
printf("%s\n", usage);
return EXIT_FAILURE;
}

char *suffix = multiple ? "" : argv[1] == NULL ? "" : argv[1];
char *string = argv[0];

char *base = basename(string, suffix);
if (print_zero) {
printf("%s", base);
putchar(0);
} else {
printf("%s\n", base);
}

if (multiple) {
int index = 1;
while (index < argc) {
string = argv[index];
base = basename(string, suffix);
if (print_zero) {
printf("%s", base);
putchar(0);
} else {
printf("%s\n", base);
}

index++;
}
}
}
1 change: 1 addition & 0 deletions utils.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ rm
rmdir
sleep
cksum
basename