mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Add strPathAbsolute() and strLstRemoveIdx().
strPathAbsolute() generates an absolute path from an absolute base path and an absolute/relative path. strLstRemoveIdx() is a support function based on lstRemoveIdx().
This commit is contained in:
parent
9421493d09
commit
174cb7b3af
@ -429,7 +429,7 @@ common/type/list.o: common/type/list.c build.auto.h common/assert.h common/debug
|
||||
common/type/mcv.o: common/type/mcv.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/list.h common/type/mcv.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c common/type/mcv.c -o common/type/mcv.o
|
||||
|
||||
common/type/string.o: common/type/string.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/macro.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h
|
||||
common/type/string.o: common/type/string.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/macro.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c common/type/string.c -o common/type/string.o
|
||||
|
||||
common/type/stringList.o: common/type/stringList.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h
|
||||
|
@ -13,6 +13,7 @@ String Handler
|
||||
#include "common/macro.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/type/string.h"
|
||||
#include "common/type/stringList.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constant strings that are generally useful
|
||||
@ -21,6 +22,7 @@ STRING_EXTERN(BRACKETL_STR, "[");
|
||||
STRING_EXTERN(BRACKETR_STR, "]");
|
||||
STRING_EXTERN(CR_STR, "\r");
|
||||
STRING_EXTERN(DOT_STR, ".");
|
||||
STRING_EXTERN(DOTDOT_STR, "..");
|
||||
STRING_EXTERN(EMPTY_STR, "");
|
||||
STRING_EXTERN(EQ_STR, "=");
|
||||
STRING_EXTERN(FALSE_STR, "false");
|
||||
@ -594,6 +596,85 @@ strPath(const String *this)
|
||||
end - this->buffer <= 1 ? (size_t)(end - this->buffer) : (size_t)(end - this->buffer - 1)));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Combine with a base path to get an absolute path
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
strPathAbsolute(const String *this, const String *base)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, this);
|
||||
FUNCTION_TEST_PARAM(STRING, base);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
String *result = NULL;
|
||||
|
||||
// Path is already absolute so just return it
|
||||
if (strBeginsWith(this, FSLASH_STR))
|
||||
{
|
||||
result = strDup(this);
|
||||
}
|
||||
// Else we'll need to construct the absolute path. You would hope we could use realpath() here but it is so broken in the
|
||||
// Posix spec that is seems best avoided.
|
||||
else
|
||||
{
|
||||
ASSERT(base != NULL);
|
||||
|
||||
// Base must be absolute to start
|
||||
if (!strBeginsWith(base, FSLASH_STR))
|
||||
THROW_FMT(AssertError, "base path '%s' is not absolute", strPtr(base));
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
StringList *baseList = strLstNewSplit(base, FSLASH_STR);
|
||||
StringList *pathList = strLstNewSplit(this, FSLASH_STR);
|
||||
|
||||
while (strLstSize(pathList) > 0)
|
||||
{
|
||||
const String *pathPart = strLstGet(pathList, 0);
|
||||
|
||||
if (strSize(pathPart) == 0)
|
||||
THROW_FMT(AssertError, "'%s' is not a valid relative path", strPtr(this));
|
||||
|
||||
if (strEq(pathPart, DOTDOT_STR))
|
||||
{
|
||||
const String *basePart = strLstGet(baseList, strLstSize(baseList) - 1);
|
||||
|
||||
if (strSize(basePart) == 0)
|
||||
{
|
||||
THROW_FMT(
|
||||
AssertError, "relative path '%s' goes back too far in base path '%s'", strPtr(this), strPtr(base));
|
||||
}
|
||||
|
||||
strLstRemoveIdx(baseList, strLstSize(baseList) - 1);
|
||||
}
|
||||
else
|
||||
strLstAdd(baseList, pathPart);
|
||||
|
||||
strLstRemoveIdx(pathList, 0);
|
||||
}
|
||||
|
||||
memContextSwitch(MEM_CONTEXT_OLD());
|
||||
|
||||
if (strLstSize(baseList) == 1)
|
||||
result = strDup(FSLASH_STR);
|
||||
else
|
||||
result = strLstJoin(baseList, "/");
|
||||
|
||||
memContextSwitch(MEM_CONTEXT_TEMP());
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
|
||||
// There should not be any stray .. or // in the final result
|
||||
if (strstr(strPtr(result), "/..") != NULL || strstr(strPtr(result), "//") != NULL)
|
||||
THROW_FMT(AssertError, "result path '%s' is not absolute", strPtr(result));
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Return string ptr
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -54,6 +54,7 @@ String *strFirstLower(String *this);
|
||||
String *strUpper(String *this);
|
||||
String *strLower(String *this);
|
||||
String *strPath(const String *this);
|
||||
String *strPathAbsolute(const String *this, const String *base);
|
||||
const char *strPtr(const String *this);
|
||||
String *strQuote(const String *this, const String *quote);
|
||||
String *strQuoteZ(const String *this, const char *quote);
|
||||
@ -121,6 +122,7 @@ STRING_DECLARE(BRACKETL_STR);
|
||||
STRING_DECLARE(BRACKETR_STR);
|
||||
STRING_DECLARE(CR_STR);
|
||||
STRING_DECLARE(DOT_STR);
|
||||
STRING_DECLARE(DOTDOT_STR);
|
||||
STRING_DECLARE(EMPTY_STR);
|
||||
STRING_DECLARE(EQ_STR);
|
||||
STRING_DECLARE(FALSE_STR);
|
||||
|
@ -628,6 +628,19 @@ strLstRemove(StringList *this, const String *item)
|
||||
FUNCTION_TEST_RETURN(lstRemove((List *)this, &item));
|
||||
}
|
||||
|
||||
StringList *
|
||||
strLstRemoveIdx(StringList *this, unsigned int listIdx)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING_LIST, this);
|
||||
FUNCTION_TEST_PARAM(UINT, listIdx);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN((StringList *)lstRemoveIdx((List *)this, listIdx));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Wrapper for lstSize()
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -43,6 +43,7 @@ StringList *strLstMergeAnti(const StringList *this, const StringList *anti);
|
||||
StringList *strLstMove(StringList *this, MemContext *parentNew);
|
||||
const char **strLstPtr(const StringList *this);
|
||||
bool strLstRemove(StringList *this, const String *item);
|
||||
StringList *strLstRemoveIdx(StringList *this, unsigned int listIdx);
|
||||
unsigned int strLstSize(const StringList *this);
|
||||
StringList *strLstSort(StringList *this, SortOrder sortOrder);
|
||||
|
||||
|
@ -61,7 +61,7 @@ testRun(void)
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("strBase() and strPath()"))
|
||||
if (testBegin("strBase(), strPath(), and strPathAbsolute()"))
|
||||
{
|
||||
TEST_RESULT_STR(strPtr(strBase(STRDEF(""))), "", "empty string");
|
||||
TEST_RESULT_STR(strPtr(strBase(STRDEF("/"))), "", "/ only");
|
||||
@ -72,6 +72,17 @@ testRun(void)
|
||||
TEST_RESULT_STR(strPtr(strPath(STRDEF("/"))), "/", "/ only");
|
||||
TEST_RESULT_STR(strPtr(strPath(STRDEF("/file"))), "/", "root path");
|
||||
TEST_RESULT_STR(strPtr(strPath(STRDEF("/dir1/dir2/file"))), "/dir1/dir2", "subdirectory file");
|
||||
|
||||
TEST_ERROR(strPathAbsolute(STRDEF("/.."), NULL), AssertError, "result path '/..' is not absolute");
|
||||
TEST_ERROR(strPathAbsolute(STRDEF("//"), NULL), AssertError, "result path '//' is not absolute");
|
||||
TEST_ERROR(strPathAbsolute(STRDEF(".."), STRDEF("path1")), AssertError, "base path 'path1' is not absolute");
|
||||
TEST_ERROR(
|
||||
strPathAbsolute(STRDEF(".."), STRDEF("/")), AssertError, "relative path '..' goes back too far in base path '/'");
|
||||
TEST_ERROR(strPathAbsolute(STRDEF("path1/"), STRDEF("/")), AssertError, "'path1/' is not a valid relative path");
|
||||
TEST_RESULT_STR_Z(strPathAbsolute(STRDEF("/"), NULL), "/", "path is already absolute");
|
||||
TEST_RESULT_STR_Z(strPathAbsolute(STRDEF(".."), STRDEF("/path1")), "/", "simple relative path");
|
||||
TEST_RESULT_STR_Z(
|
||||
strPathAbsolute(STRDEF("../path2/../path3"), STRDEF("/base1/base2")), "/base1/path3", "complex relative path");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user