1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-30 05:39:12 +02:00

Add String object to simplify string handling.

This commit is contained in:
David Steele 2017-11-26 17:49:10 -05:00
parent 7cf955425e
commit 1b3e8e0a5b
7 changed files with 223 additions and 0 deletions

View File

@ -22,6 +22,10 @@
<release-item>
<p>Add <code>memGrowRaw()</code> to memory context module.</p>
</release-item>
<release-item>
<p>Add <code>String</code> object to simplify string handling.</p>
</release-item>
</release-development-list>
</release-core-list>

View File

@ -29,4 +29,9 @@ typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
/***********************************************************************************************************************************
Include all header files in type directory for convenience
***********************************************************************************************************************************/
#include "common/type/string.h"
#endif

132
src/common/type/string.c Normal file
View File

@ -0,0 +1,132 @@
/***********************************************************************************************************************************
String Handler
***********************************************************************************************************************************/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "common/memContext.h"
#include "common/type/string.h"
/***********************************************************************************************************************************
Contains information about the string
***********************************************************************************************************************************/
struct String
{
size_t size;
char *buffer;
};
/***********************************************************************************************************************************
Create a new string from another string
***********************************************************************************************************************************/
String *
strNew(const char *string)
{
// Create object
String *this = memNew(sizeof(String));
this->size = strlen(string);
// Allocate and assign string
this->buffer = memNewRaw(this->size + 1);
strcpy(this->buffer, string);
// Return buffer
return this;
}
/***********************************************************************************************************************************
Create a new string from a format string with parameters (i.e. sprintf)
***********************************************************************************************************************************/
String *
strNewFmt(const char *format, ...)
{
// Create object
String *this = memNew(sizeof(String));
// Determine how long the allocated string needs to be
va_list argumentList;
va_start(argumentList, format);
this->size = vsnprintf(NULL, 0, format, argumentList);
va_end(argumentList);
// Allocate and assign string
this->buffer = memNewRaw(this->size + 1);
va_start(argumentList, format);
vsnprintf(this->buffer, this->size + 1, format, argumentList);
va_end(argumentList);
// Return buffer
return this;
}
/***********************************************************************************************************************************
Append a string
***********************************************************************************************************************************/
String *
strCat(String *this, const char *cat)
{
// Determine length of string to append
int sizeGrow = strlen(cat);
// Allocate and append string
this->buffer = memGrowRaw(this->buffer, this->size + sizeGrow + 1);
strcpy(this->buffer + this->size, cat);
this->size += sizeGrow;
return this;
}
/***********************************************************************************************************************************
Append a formatted string
***********************************************************************************************************************************/
String *
strCatFmt(String *this, const char *format, ...)
{
// Determine how long the allocated string needs to be
va_list argumentList;
va_start(argumentList, format);
int sizeGrow = vsnprintf(NULL, 0, format, argumentList);
va_end(argumentList);
// Allocate and append string
this->buffer = memGrowRaw(this->buffer, this->size + sizeGrow + 1);
va_start(argumentList, format);
vsnprintf(this->buffer + this->size, sizeGrow + 1, format, argumentList);
va_end(argumentList);
this->size += sizeGrow;
// Return buffer
return this;
}
/***********************************************************************************************************************************
Return string ptr
***********************************************************************************************************************************/
const char *
strPtr(const String *this)
{
return (const char *)this->buffer;
}
/***********************************************************************************************************************************
Return string size
***********************************************************************************************************************************/
size_t
strSize(const String *this)
{
return this->size;
}
/***********************************************************************************************************************************
Free the string
***********************************************************************************************************************************/
void
strFree(String *this)
{
memFree(this->buffer);
memFree(this);
}

23
src/common/type/string.h Normal file
View File

@ -0,0 +1,23 @@
/***********************************************************************************************************************************
String Handler
***********************************************************************************************************************************/
#ifndef COMMON_TYPE_STRING_H
#define COMMON_TYPE_STRING_H
/***********************************************************************************************************************************
String object
***********************************************************************************************************************************/
typedef struct String String;
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
String *strNew(const char *string);
String *strNewFmt(const char *format, ...);
size_t strSize(const String *this);
String *strCat(String *this, const char *cat);
String *strCatFmt(String *this, const char *format, ...);
const char *strPtr(const String *this);
void strFree(String *this);
#endif

View File

@ -125,6 +125,16 @@ my $oTestDef =
'common/memContext' => TESTDEF_COVERAGE_FULL,
},
},
{
&TESTDEF_NAME => 'type-string',
&TESTDEF_TOTAL => 2,
&TESTDEF_C => true,
&TESTDEF_COVERAGE =>
{
'common/type/string' => TESTDEF_COVERAGE_FULL,
},
},
{
&TESTDEF_NAME => 'encode',
&TESTDEF_TOTAL => 1,

View File

@ -149,6 +149,13 @@ Macros to ease the use of common data types
#define TEST_RESULT_BOOL(statement, resultExpected, ...) \
TEST_RESULT_BOOL_PARAM(statement, resultExpected, ==, __VA_ARGS__);
#define TEST_RESULT_CHAR_PARAM(statement, resultExpected, typeOp, ...) \
TEST_RESULT(statement, resultExpected, char, "%c", TEST_TYPE_FORMAT, typeOp, TEST_TYPE_COMPARE, __VA_ARGS__);
#define TEST_RESULT_CHAR(statement, resultExpected, ...) \
TEST_RESULT_CHAR_PARAM(statement, resultExpected, ==, __VA_ARGS__);
#define TEST_RESULT_CHAR_NE(statement, resultExpected, ...) \
TEST_RESULT_CHAR_PARAM(statement, resultExpected, !=, __VA_ARGS__);
#define TEST_RESULT_DOUBLE_PARAM(statement, resultExpected, typeOp, ...) \
TEST_RESULT(statement, resultExpected, double, "%f", TEST_TYPE_FORMAT, typeOp, TEST_TYPE_COMPARE, __VA_ARGS__);
#define TEST_RESULT_DOUBLE(statement, resultExpected, ...) \

View File

@ -0,0 +1,42 @@
/***********************************************************************************************************************************
Test Strings
***********************************************************************************************************************************/
/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
void testRun()
{
// *****************************************************************************************************************************
if (testBegin("strNew() and strFree()"))
{
String *string = strNew("static string");
TEST_RESULT_STR(strPtr(string), "static string", "new with static string");
TEST_RESULT_INT(strSize(string), 13, "check size");
TEST_RESULT_INT(strlen(strPtr(string)), 13, "check size with strlen()");
TEST_RESULT_CHAR(strPtr(string)[2], 'a', "check character");
strFree(string);
string = strNewFmt("formatted %s %04d", "string", 1);
TEST_RESULT_STR(strPtr(string), "formatted string 0001", "new with formatted string");
strFree(string);
}
// *****************************************************************************************************************************
if (testBegin("strCat and strCatFmt()"))
{
String *string = strNew("XXXX");
String *string2 = strNew("ZZZZ");
strCat(string, "YYYY");
TEST_RESULT_STR(strPtr(string), "XXXXYYYY", "cat string");
strCatFmt(string, "%05d", 777);
TEST_RESULT_STR(strPtr(string), "XXXXYYYY00777", "cat formatted string");
TEST_RESULT_STR(strPtr(string2), "ZZZZ", "check unaltered string");
strFree(string);
strFree(string2);
}
}