Skip to content

Commit c545a68

Browse files
committed
Absolute ROOT relative
TODO: Path like C:abc means not absolute path it's need the cwd to handling normalize
1 parent 91d0352 commit c545a68

File tree

4 files changed

+55
-75
lines changed

4 files changed

+55
-75
lines changed

include/cpj.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,9 @@ static inline cpj_size_t cpj_path_join_module(
250250
* @param path_style Style depending on the operating system. So this should
251251
* detect whether we should use windows or unix paths.
252252
* @param path The path which will be inspected.
253-
* @param length The output of the root length.
253+
* @return The inspected root length of the path.
254254
*/
255-
CPJ_PUBLIC void cpj_path_get_root(cpj_path_style_t path_style, const cpj_char_t *path, cpj_size_t *length);
255+
CPJ_PUBLIC cpj_size_t cpj_path_get_root(cpj_path_style_t path_style, const cpj_char_t *path);
256256

257257
/**
258258
* @brief Changes the root of a path.
@@ -289,7 +289,10 @@ CPJ_PUBLIC cpj_size_t cpj_path_change_root(
289289
* @param path The path which will be checked.
290290
* @return Returns true if the path is absolute or false otherwise.
291291
*/
292-
CPJ_PUBLIC bool cpj_path_is_absolute(cpj_path_style_t path_style, const cpj_char_t *path);
292+
static inline bool cpj_path_is_absolute(cpj_path_style_t path_style, const cpj_char_t *path)
293+
{
294+
return cpj_path_get_root(path_style, path) > 0;
295+
}
293296

294297
/**
295298
* @brief Determine whether the path is relative or not.
@@ -302,7 +305,10 @@ CPJ_PUBLIC bool cpj_path_is_absolute(cpj_path_style_t path_style, const cpj_char
302305
* @param path The path which will be checked.
303306
* @return Returns true if the path is relative or false otherwise.
304307
*/
305-
CPJ_PUBLIC bool cpj_path_is_relative(cpj_path_style_t path_style, const cpj_char_t *path);
308+
static inline bool cpj_path_is_relative(cpj_path_style_t path_style, const cpj_char_t *path)
309+
{
310+
return cpj_path_get_root(path_style, path) == 0;
311+
}
306312

307313
/**
308314
* @brief Gets the basename of a file path.

src/cpj.c

Lines changed: 26 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,15 @@ static const cpj_char_t *cpj_path_find_next_stop(cpj_path_style_t path_style, co
8484
return c;
8585
} /* cpj_path_find_next_stop */
8686

87-
static void cpj_path_get_root_windows(const cpj_char_t *path, cpj_size_t *length)
87+
static cpj_size_t cpj_path_get_root_windows(const cpj_char_t *path)
8888
{
8989
const cpj_char_t *c;
90-
90+
cpj_size_t length = 0;
9191
// We can not determine the root if this is an empty string. So we set the
9292
// root to NULL and the length to zero and cancel the whole thing.
9393
c = path;
94-
*length = 0;
9594
if (!*c) {
96-
return;
95+
return length;
9796
}
9897

9998
// Now we have to verify whether this is a windows network path (UNC), which
@@ -107,8 +106,8 @@ static void cpj_path_get_root_windows(const cpj_char_t *path, cpj_size_t *length
107106
if (!cpj_path_is_separator(CPJ_STYLE_WINDOWS, *c)) {
108107
// Okay, this is not a network path but we still use the backslash as a
109108
// root.
110-
++(*length);
111-
return;
109+
++length;
110+
return length;
112111
}
113112

114113
// A device path is a path which starts with "\\." or "\\?". A device path
@@ -124,8 +123,8 @@ static void cpj_path_get_root_windows(const cpj_char_t *path, cpj_size_t *length
124123
// That's a device path, and the root must be either "\\.\" or "\\?\"
125124
// which is 4 characters long. (at least that's how Windows
126125
// GetFullPathName behaves.)
127-
*length = 4;
128-
return;
126+
length = 4;
127+
return length;
129128
}
130129

131130
// We will grab anything up to the next stop. The next stop might be a '\0'
@@ -149,44 +148,37 @@ static void cpj_path_get_root_windows(const cpj_char_t *path, cpj_size_t *length
149148
}
150149

151150
// Finally, calculate the size of the root.
152-
*length = (cpj_size_t)(c - path);
153-
return;
151+
length = (cpj_size_t)(c - path);
152+
return length;
154153
}
155154

156155
// Move to the next and check whether this is a colon.
157156
if (*++c == ':') {
158-
*length = 2;
157+
length = 2;
159158

160159
// Now check whether this is a backslash (or slash). If it is not, we could
161160
// assume that the next character is a '\0' if it is a valid path. However,
162161
// we will not assume that - since ':' is not valid in a path it must be a
163162
// mistake by the caller than. We will try to understand it anyway.
164163
if (cpj_path_is_separator(CPJ_STYLE_WINDOWS, *(++c))) {
165-
*length = 3;
164+
length = 3;
166165
}
167166
}
167+
return length;
168168
} /* cpj_path_get_root_windows */
169169

170-
static void cpj_path_get_root_unix(const cpj_char_t *path, cpj_size_t *length)
170+
static cpj_size_t cpj_path_get_root_unix(const cpj_char_t *path)
171171
{
172172
// The slash of the unix path represents the root. There is no root if there
173173
// is no slash.
174-
if (cpj_path_is_separator(CPJ_STYLE_UNIX, *path)) {
175-
*length = 1;
176-
} else {
177-
*length = 0;
178-
}
174+
return cpj_path_is_separator(CPJ_STYLE_UNIX, *path) ? 1 : 0;
179175
} /* cpj_path_get_root_unix */
180176

181-
void cpj_path_get_root(cpj_path_style_t path_style, const cpj_char_t *path, cpj_size_t *length)
177+
cpj_size_t cpj_path_get_root(cpj_path_style_t path_style, const cpj_char_t *path)
182178
{
183179
// We use a different implementation here based on the configuration of the
184180
// library.
185-
if (path_style == CPJ_STYLE_WINDOWS) {
186-
cpj_path_get_root_windows(path, length);
187-
} else {
188-
cpj_path_get_root_unix(path, length);
189-
}
181+
return path_style == CPJ_STYLE_WINDOWS ? cpj_path_get_root_windows(path) : cpj_path_get_root_unix(path);
190182
} /* cpj_path_get_root */
191183

192184
static cpj_char_t cpj_path_get_char(cpj_join_state_t *state, cpj_iterator_t *it)
@@ -204,7 +196,7 @@ static void cpj_path_update_root_length(cpj_join_state_t *state, cpj_iterator_t
204196
{
205197
state->path_total_size += state->path_list_p[it->list_pos].size;
206198
if (state->is_module || it->list_pos == 0) {
207-
cpj_path_get_root(state->style, state->path_list_p[it->list_pos].ptr, &it->root_length);
199+
it->root_length = cpj_path_get_root(state->style, state->path_list_p[it->list_pos].ptr);
208200
}
209201
} /* cpj_path_update_root_length */
210202

@@ -992,8 +984,8 @@ cpj_size_t cpj_path_get_relative(
992984
// First we compare the roots of those two paths. If the roots are not equal
993985
// we can't continue, since there is no way to get a relative path from
994986
// different roots.
995-
cpj_path_get_root(path_style, base_directory, &base_root_length);
996-
cpj_path_get_root(path_style, path, &path_root_length);
987+
base_root_length = cpj_path_get_root(path_style, base_directory);
988+
path_root_length = cpj_path_get_root(path_style, path);
997989
if (base_root_length != path_root_length ||
998990
!cpj_path_is_string_equal(path_style, base_directory, path, base_root_length, path_root_length)) {
999991
cpj_path_terminate_output(buffer, buffer_size, pos);
@@ -1093,7 +1085,7 @@ cpj_size_t cpj_path_change_root(
10931085

10941086
// First we need to determine the actual size of the root which we will
10951087
// change.
1096-
cpj_path_get_root(path_style, path, &root_length);
1088+
root_length = cpj_path_get_root(path_style, path);
10971089

10981090
// Now we determine the sizes of the new root and the path. We need that to
10991091
// determine the size of the part after the root (the tail).
@@ -1118,24 +1110,6 @@ cpj_size_t cpj_path_change_root(
11181110
return new_path_size;
11191111
}
11201112

1121-
bool cpj_path_is_absolute(cpj_path_style_t path_style, const cpj_char_t *path)
1122-
{
1123-
cpj_size_t length;
1124-
1125-
// We grab the root of the path. This root does not include the first
1126-
// separator of a path.
1127-
cpj_path_get_root(path_style, path, &length);
1128-
1129-
// Now we can determine whether the root is absolute or not.
1130-
return cpj_path_is_root_absolute(path_style, path, length);
1131-
}
1132-
1133-
bool cpj_path_is_relative(cpj_path_style_t path_style, const cpj_char_t *path)
1134-
{
1135-
// The path is relative if it is not absolute.
1136-
return !cpj_path_is_absolute(path_style, path);
1137-
}
1138-
11391113
void cpj_path_get_basename(
11401114
cpj_path_style_t path_style, const cpj_char_t *path, const cpj_char_t **basename, cpj_size_t *length
11411115
)
@@ -1176,7 +1150,7 @@ cpj_size_t cpj_path_change_basename(
11761150

11771151
// So there is no segment in this path. First we grab the root and output
11781152
// that. We are not going to modify the root in any way.
1179-
cpj_path_get_root(path_style, path, &root_size);
1153+
root_size = cpj_path_get_root(path_style, path);
11801154
pos = cpj_path_output_sized(buffer, buffer_size, 0, path, root_size);
11811155

11821156
// We have to trim the separators from the beginning of the new basename.
@@ -1282,7 +1256,7 @@ cpj_size_t cpj_path_change_extension(
12821256
// So there is no segment in this path. First we grab the root and output
12831257
// that. We are not going to modify the root in any way. If there is no
12841258
// root, this will end up with a root size 0, and nothing will be written.
1285-
cpj_path_get_root(path_style, path, &root_size);
1259+
root_size = cpj_path_get_root(path_style, path);
12861260
pos = cpj_path_output_sized(buffer, buffer_size, 0, path, root_size);
12871261

12881262
// Add a dot if the submitted value doesn't have any.
@@ -1349,8 +1323,8 @@ cpj_path_get_intersection(cpj_path_style_t path_style, const cpj_char_t *path_ba
13491323
// We first compare the two roots. We just return zero if they are not equal.
13501324
// This will also happen to return zero if the paths are mixed relative and
13511325
// absolute.
1352-
cpj_path_get_root(path_style, path_base, &base_root_length);
1353-
cpj_path_get_root(path_style, path_other, &other_root_length);
1326+
base_root_length = cpj_path_get_root(path_style, path_base);
1327+
other_root_length = cpj_path_get_root(path_style, path_other);
13541328
if (!cpj_path_is_string_equal(path_style, path_base, path_other, base_root_length, other_root_length)) {
13551329
return 0;
13561330
}
@@ -1413,7 +1387,7 @@ bool cpj_path_get_first_segment(cpj_path_style_t path_style, const cpj_char_t *p
14131387

14141388
// We skip the root since that's not part of the first segment. The root is
14151389
// treated as a separate entity.
1416-
cpj_path_get_root(path_style, path, &length);
1390+
length = cpj_path_get_root(path_style, path);
14171391
segments = path + length;
14181392

14191393
// Now, after we skipped the root we can continue and find the actual segment
@@ -1585,7 +1559,7 @@ cpj_path_style_t cpj_path_guess_style(const cpj_char_t *path)
15851559
// First we determine the root. Only windows roots can be longer than a single
15861560
// slash, so if we can determine that it starts with something like "C:", we
15871561
// know that this is a windows path.
1588-
cpj_path_get_root_windows(path, &root_length);
1562+
root_length = cpj_path_get_root_windows(path);
15891563
if (root_length > 1) {
15901564
return CPJ_STYLE_WINDOWS;
15911565
}

test/root_test.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ int root_relative_windows(void)
103103
{
104104
cpj_size_t length;
105105

106-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "..\\hello\\world.txt", &length);
106+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "..\\hello\\world.txt");
107107

108108
if (length != 0) {
109109
return EXIT_FAILURE;
@@ -116,7 +116,7 @@ int root_relative_drive(void)
116116
{
117117
cpj_size_t length;
118118

119-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "C:test.txt", &length);
119+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "C:test.txt");
120120

121121
if (length != 2) {
122122
return EXIT_FAILURE;
@@ -129,7 +129,7 @@ int root_device_question_mark(void)
129129
{
130130
cpj_size_t length;
131131

132-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\\\?\\mydevice\\test", &length);
132+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\\\?\\mydevice\\test");
133133

134134
if (length != 4) {
135135
return EXIT_FAILURE;
@@ -142,7 +142,7 @@ int root_device_dot(void)
142142
{
143143
cpj_size_t length;
144144

145-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\\\.\\mydevice\\test", &length);
145+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\\\.\\mydevice\\test");
146146

147147
if (length != 4) {
148148
return EXIT_FAILURE;
@@ -155,7 +155,7 @@ int root_device_unc(void)
155155
{
156156
cpj_size_t length;
157157

158-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\\\.\\UNC\\LOCALHOST\\c$\\temp\\test-file.txt", &length);
158+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\\\.\\UNC\\LOCALHOST\\c$\\temp\\test-file.txt");
159159

160160
if (length != 4) {
161161
return EXIT_FAILURE;
@@ -168,7 +168,7 @@ int root_unc(void)
168168
{
169169
cpj_size_t length;
170170

171-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\\\server\\folder\\data", &length);
171+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\\\server\\folder\\data");
172172

173173
if (length != 16) {
174174
return EXIT_FAILURE;
@@ -181,7 +181,7 @@ int root_absolute_drive(void)
181181
{
182182
cpj_size_t length;
183183

184-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "C:\\test.txt", &length);
184+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "C:\\test.txt");
185185

186186
if (length != 3) {
187187
return EXIT_FAILURE;
@@ -194,7 +194,7 @@ int root_unix_drive(void)
194194
{
195195
cpj_size_t length;
196196

197-
cpj_path_get_root(CPJ_STYLE_UNIX, "C:\\test.txt", &length);
197+
length = cpj_path_get_root(CPJ_STYLE_UNIX, "C:\\test.txt");
198198

199199
if (length != 0) {
200200
return EXIT_FAILURE;
@@ -207,7 +207,7 @@ int root_unix_backslash(void)
207207
{
208208
cpj_size_t length;
209209

210-
cpj_path_get_root(CPJ_STYLE_UNIX, "\\folder\\", &length);
210+
length = cpj_path_get_root(CPJ_STYLE_UNIX, "\\folder\\");
211211

212212
if (length != 0) {
213213
return EXIT_FAILURE;
@@ -220,7 +220,7 @@ int root_windows_slash(void)
220220
{
221221
cpj_size_t length;
222222

223-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "/test.txt", &length);
223+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "/test.txt");
224224

225225
if (length != 1) {
226226
return EXIT_FAILURE;
@@ -233,7 +233,7 @@ int root_windows_backslash(void)
233233
{
234234
cpj_size_t length;
235235

236-
cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\test.txt", &length);
236+
length = cpj_path_get_root(CPJ_STYLE_WINDOWS, "\\test.txt");
237237

238238
if (length != 1) {
239239
return EXIT_FAILURE;
@@ -246,7 +246,7 @@ int root_relative(void)
246246
{
247247
cpj_size_t length;
248248

249-
cpj_path_get_root(CPJ_STYLE_UNIX, "test.txt", &length);
249+
length = cpj_path_get_root(CPJ_STYLE_UNIX, "test.txt");
250250

251251
if (length != 0) {
252252
return EXIT_FAILURE;
@@ -259,7 +259,7 @@ int root_absolute(void)
259259
{
260260
cpj_size_t length;
261261

262-
cpj_path_get_root(CPJ_STYLE_UNIX, "/test.txt", &length);
262+
length = cpj_path_get_root(CPJ_STYLE_UNIX, "/test.txt");
263263

264264
if (length != 1) {
265265
return EXIT_FAILURE;

0 commit comments

Comments
 (0)