-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathext.c
64 lines (57 loc) · 1.75 KB
/
ext.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
* Copyright (c) 2018-present StackPath, LLC
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* ext.c -- parse or strip file extensions from filenames
*/
#define _GNU_SOURCE // for GNU basename()
#include "ext.h"
#include <stdlib.h> // for malloc()
#include <string.h> // for GNU basename(), strcpy(), strlen(), strrchr()
/* These functions are currently incompatible with the POSIX implementation of
* basename(). We need the GNU implementation instead.
*
* Do not include libgen.h otherwise you'll get the POSIX version.
*/
char *ext(char *path) {
char *filename = basename(path);
char *p = strrchr(filename, '.');
/*
* When p is null filename is for an unhidden file without an extension. When
* strlens are the same filename is for a hidden file without an extension.
* In either case, we want to return an empty string.
*/
if (!p || strlen(p) == strlen(filename)) {
return "";
}
/*
* The rest of the time, p + 1 returns the extension without the dot.
*/
return p + 1;
}
char *noext(char *path) {
char *filename = basename(path);
char *p = strrchr(filename, '.');
/*
* When p is null filename is for an unhidden file without an extension. When
* strlens are the same filename is for a hidden file without an extension.
* In either case, we want to return path unaltered.
*/
if (!p || strlen(p) == strlen(filename)) {
return path;
}
/*
* The rest of the time we strip off the extension including the dot.
*/
p[0] = '\0';
return path;
}
char *noext_copy(const char *path) {
char *path_copy;
path_copy = malloc(strlen(path) + 1);
strcpy(path_copy, path);
return noext(path_copy);
}