-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpath_util.c
More file actions
82 lines (73 loc) · 2.34 KB
/
path_util.c
File metadata and controls
82 lines (73 loc) · 2.34 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* utilities for manipulating paths */
#include <glib.h>
#include <libgen.h>
#include <string.h>
#include "util.h"
#include "path_util.h"
#include "log.h"
#include "tagdb.h"
/* first and rest must be able to hold the entire
* length of the path
*/
void chug_path(const char *path, char *first, char *rest)
{
/* part of the path that follows the root path character(s) */
const char *after_root;
size_t after_root_length;
/* length of the first path component */
size_t part_length;
after_root = g_path_skip_root(path);
after_root_length = strlen(after_root);
part_length = strcspn(after_root, "/");
g_memmove(first, after_root, part_length);
first[part_length] = 0;
g_memmove(rest, after_root + part_length, part_length - after_root_length);
}
/* splits a path into a NULL terminated array of path components */
char **split_path (const char *path)
{
return g_strsplit(g_path_skip_root(path), "/", -1);
}
gboolean path_has_component_with_test (const char *path, path_test test, const char *test_data)
{
if (!path || path[0] == '\0')
{
return FALSE;
}
size_t path_length = strlen(path);
char *first = g_alloca(path_length);
char *rest = g_alloca(path_length);
chug_path(path, first, rest);
if (test(first, test_data))
{
return TRUE;
}
return path_has_component_with_test(rest, test, test_data);
}
gboolean path_has_component_with_prefix (const char *path, const char *prefix)
{
return path_has_component_with_test(path, (path_test) g_str_has_prefix, prefix);
}
gboolean path_has_component_with_suffix (const char *path, const char *suffix)
{
return path_has_component_with_test(path, (path_test) g_str_has_suffix, suffix);
}
gboolean path_has_component (const char *path, const char *component)
{
return path_has_component_with_test(path, (path_test) g_str_equal, component);
}
/* returns the path upto a component that contains the given substring */
char *path_before_component (const char *path, const char *substr)
{
// search the substring
// if it's found, seek back to the closest path separator and return
// the part before it.
char *res = NULL;
char *match = strstr(path, substr);
if (match)
{
while (match[0] != '/') match--;
res = g_strndup(path, match - path); // safe since match != NULL
}
return res;
}