path: add a function to check for path suffix
We have a function to strip the path suffix from a commit, but we don't have one to check for a path suffix. For a plain filename, we can use basename, but that requires an allocation, since POSIX allows it to modify its argument. Refactor strip_path_suffix into a helper function and a new function, ends_with_path_components, to meet this need. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
brian m. carlson committed
Aug 25, 2019 at 23:33 UTC
ce17feb1b3ecfb0344af9b9111a4b4d313d51d7a
2 files changed
+33
-9
path.c
+30
-9
@@ -1221,31 +1221,52 @@ static inline int chomp_trailing_dir_sep(const char *path, int len)
1221
}
1222
1223
/*
1224
- * If path ends with suffix (complete path components), returns the
1225
- * part before suffix (sans trailing directory separators).
1226
- * Otherwise returns NULL.
1224
+ * If path ends with suffix (complete path components), returns the offset of
1225
+ * the last character in the path before the suffix (sans trailing directory
1226
+ * separators), and -1 otherwise.
1227
*/
1228
-char *strip_path_suffix(const char *path, const char *suffix)
1228
+static ssize_t stripped_path_suffix_offset(const char *path, const char *suffix)
1229
{
1230
int path_len = strlen(path), suffix_len = strlen(suffix);
1231
1232
while (suffix_len) {
1233
if (!path_len)
1234
- return NULL;
1234
+ return -1;
1235
1236
if (is_dir_sep(path[path_len - 1])) {
1237
if (!is_dir_sep(suffix[suffix_len - 1]))
1238
- return NULL;
1238
+ return -1;
1239
path_len = chomp_trailing_dir_sep(path, path_len);
1240
suffix_len = chomp_trailing_dir_sep(suffix, suffix_len);
1241
}
1242
else if (path[--path_len] != suffix[--suffix_len])
1243
- return NULL;
1243
+ return -1;
1244
}
1245
1246
if (path_len && !is_dir_sep(path[path_len - 1]))
1247
- return NULL;
1248
- return xstrndup(path, chomp_trailing_dir_sep(path, path_len));
1247
+ return -1;
1248
+ return chomp_trailing_dir_sep(path, path_len);
1249
+}
1250
+
1251
+/*
1252
+ * Returns true if the path ends with components, considering only complete path
1253
+ * components, and false otherwise.
1254
+ */
1255
+int ends_with_path_components(const char *path, const char *components)
1256
+{
1257
+ return stripped_path_suffix_offset(path, components) != -1;
1258
+}
1259
+
1260
+/*
1261
+ * If path ends with suffix (complete path components), returns the
1262
+ * part before suffix (sans trailing directory separators).
1263
+ * Otherwise returns NULL.
1264
+ */
1265
+char *strip_path_suffix(const char *path, const char *suffix)
1266
+{
1267
+ ssize_t offset = stripped_path_suffix_offset(path, suffix);
1268
+
1269
+ return offset == -1 ? NULL : xstrndup(path, offset);
1270
}
1271
1272
int daemon_avoid_alias(const char *p)
path.h
+3
@@ -193,4 +193,7 @@ const char *git_path_merge_head(struct repository *r);
193
const char *git_path_fetch_head(struct repository *r);
194
const char *git_path_shallow(struct repository *r);
195
196
+
197
+int ends_with_path_components(const char *path, const char *components);
198
+
199
#endif /* PATH_H */