#define _POSIX_C_SOURCE 200809L #include #include #include int main(int argc, char ** argv) { int suffix_present = 0, i, j; char *basename; char c; int basename_length = 0, last_slash = 0; int suffix_length = 0; /* Basename takes two arguments, one for the path itself and an optional one for a suffix to remove (e.g. ".c" to remove the C file extension). Here, we check for that second argument to determine if we need to remove an extension. If there aren't multiple arguments, check if a path was even given. If not, the POSIX spec says to just return a newline. */ if(argc > 2) { suffix_present = 1; } else if(argc == 1) { printf("\n"); return 0; } /* If the path is just //, the POSIX spec also says to return newline */ if(strcmp(argv[1], "//") == 0) { printf("\n"); return 0; } i = 0; /* Find the end of the path (probably could've just used strlen) */ for(c = argv[1][i]; c != '\0'; c = argv[1][i]) { i++; } /* If the last character of the path is /, then remove it */ if(argv[1][i-1] == '/') { argv[1][i-1] = '\0'; } i = 0; /* Find the last slash in the path */ for(c = argv[1][i]; c != '\0'; c = argv[1][i]) { if(c == '/') { last_slash = i; } i++; } i = last_slash + 1; /* Figure out how long the basename is */ for(c = argv[1][i]; c != '\0'; c = argv[1][i]) { basename_length++; i++; } /* Allocate memory for the basename; fail out if we can't */ basename = calloc(basename_length + 1, sizeof(*basename)); if(basename == NULL) { fprintf(stderr, "%s: Could not allocate sufficient memory\n", argv[0]); return 1; } i = last_slash + 1; /* Transfer the basename to the array */ for(c = argv[1][i]; c != '\0'; c = argv[1][i]) { basename[i - (last_slash + 1)] = c; i++; } basename[basename_length] = '\0'; /* don't forget the null! */ /* If we need to remove a suffix, check if the end of the string is actually equal to the suffix and, if it is, replace the first character of the suffix with a null character. */ if(suffix_present && strcmp(basename, argv[2]) != 0) { i = 0; for(c = argv[2][i]; c != '\0'; c = argv[2][i]) { suffix_length++; i++; } j = suffix_length - 1; for(i = basename_length - 1; i > 0; i--) { if(basename[i] != argv[2][j]) { break; } else if(j == 0) { basename[i] = '\0'; i = 0; } j--; } } /* Print the basename, free the memory, and quit! */ printf("%s\n", basename); free(basename); return 0; }