Skip to content

Commit fd7b481

Browse files
authored
Merge pull request #41 from enzoevers/separate-base-path-from-string-path
Create ExtractLastPartOfPath(...)
2 parents 82a600d + 7a03b04 commit fd7b481

File tree

3 files changed

+422
-0
lines changed

3 files changed

+422
-0
lines changed

CoDeLib/FileUtils/src/FileUtils.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <assert.h>
33
#include <ctype.h>
44
#include <stdbool.h>
5+
#include <stdint.h>
56
#include <stdlib.h>
67
#include <string.h>
78

@@ -271,6 +272,75 @@ bool PathExists(const char *pPath) {
271272
return pathExists;
272273
}
273274

275+
size_t ExtractLastPartOfPath(const char *const pPath, char *const pDestBuffer,
276+
size_t destBufferSize) {
277+
if (pPath == NULL || pDestBuffer == NULL || destBufferSize == 0) {
278+
return SIZE_MAX;
279+
}
280+
281+
const size_t pathLenght = strnlen(pPath, MAX_PATH_LENGTH_WTH_TERMINATOR);
282+
if (pathLenght == 0 || pathLenght == MAX_PATH_LENGTH_WTH_TERMINATOR) {
283+
return SIZE_MAX;
284+
}
285+
286+
if (pathLenght == 1 && (pPath[0] == '/' || pPath[0] == '\\')) {
287+
return SIZE_MAX;
288+
}
289+
290+
char *pLocalPath = (char *)calloc(pathLenght + 1, sizeof(char));
291+
memcpy(pLocalPath, pPath, pathLenght + 1);
292+
293+
const char lastChar = pLocalPath[pathLenght - 1];
294+
bool isDir = lastChar == '/' || lastChar == '\\';
295+
296+
if (isDir) {
297+
// Remove the last separator to make getting the file or directory name
298+
// more generic.
299+
pLocalPath[pathLenght - 1] = '\0';
300+
}
301+
302+
char *pLastForwardSeparator = strrchr(pLocalPath, '/');
303+
char *pLastBackwardSeparator = strrchr(pLocalPath, '\\');
304+
char *pLastSeparator = pLastForwardSeparator > pLastBackwardSeparator
305+
? pLastForwardSeparator
306+
: pLastBackwardSeparator;
307+
308+
size_t startIndexOfNameInPath = SIZE_MAX;
309+
char *pLastPart = NULL;
310+
311+
if (pLastSeparator == NULL) {
312+
// No separator found, so the last part is the whole path.
313+
startIndexOfNameInPath = 0;
314+
pLastPart = pLocalPath;
315+
} else {
316+
startIndexOfNameInPath = (pLastSeparator - pLocalPath) + 1;
317+
pLastPart = pLastSeparator + 1;
318+
}
319+
320+
if (isDir) {
321+
// Add the last separator back if it was removed.
322+
pLocalPath[pathLenght - 1] = lastChar;
323+
}
324+
325+
const size_t lastPartLength =
326+
strnlen(pLastPart, MAX_PATH_LENGTH_WTH_TERMINATOR);
327+
328+
if (lastPartLength == MAX_PATH_LENGTH_WTH_TERMINATOR) {
329+
free(pLocalPath);
330+
return SIZE_MAX;
331+
}
332+
333+
if (lastPartLength >= destBufferSize) {
334+
free(pLocalPath);
335+
return SIZE_MAX;
336+
}
337+
338+
memcpy(pDestBuffer, pLastPart, lastPartLength + 1);
339+
340+
free(pLocalPath);
341+
return startIndexOfNameInPath;
342+
}
343+
274344
void OpenFileWithMode(FILE **pInFile, RaiiString *pFullPath, char *pOpenMode) {
275345
*pInFile = fopen(pFullPath->pString, pOpenMode);
276346
if (*pInFile == NULL) {

0 commit comments

Comments
 (0)