replace sbs_cut with more powerful sbs_substr

This commit is contained in:
Enno Rehling 2018-11-27 20:50:58 +01:00
parent 3be5211a53
commit d4d7394e29
4 changed files with 58 additions and 13 deletions

View File

@ -1550,7 +1550,7 @@ void pump_paragraph(sbstring *sbp, stream *out, size_t maxlen, bool isfinal)
return;
}
else if (next > begin + maxlen) {
size_t len = pos - begin;
ptrdiff_t len = pos - begin;
swrite(begin, 1, len, out);
newline(out);
@ -1558,8 +1558,8 @@ void pump_paragraph(sbstring *sbp, stream *out, size_t maxlen, bool isfinal)
++pos;
++len;
}
assert(len <= INT_MAX);
sbs_cut(sbp, (int)len);
assert(len <= SIZE_MAX);
sbs_substr(sbp, len, SIZE_MAX);
break;
}
pos = next;

View File

@ -298,19 +298,24 @@ void sbs_strcpy(struct sbstring *sbs, const char *str)
assert(sbs->begin + sbs->size >= sbs->end);
}
void sbs_cut(sbstring *sbs, int bytes)
void sbs_substr(sbstring *sbs, ptrdiff_t pos, size_t len)
{
if (bytes > 0) {
size_t len = sbs_length(sbs) - bytes;
memmove(sbs->begin, sbs->begin + bytes, len + 1);
sbs->end = sbs->begin + len;
if (pos > sbs->end - sbs->begin) {
/* starting past end of string, do nothing */
sbs->end = sbs->begin;
}
else if (bytes < 0) {
size_t len = sbs_length(sbs) + bytes;
if (pos >= 0) {
size_t sz = sbs->end - (sbs->begin + pos);
if (len > sz) len = sz;
if (len - pos > 0) {
memmove(sbs->begin, sbs->begin + pos, len);
}
else {
memcpy(sbs->begin, sbs->begin + pos, len);
}
sbs->end = sbs->begin + len;
sbs->end[0] = '\0';
}
assert(sbs->begin + sbs->size >= sbs->end);
assert(sbs->end[0] == '\0');
}
size_t sbs_length(const struct sbstring *sbs)

View File

@ -52,7 +52,7 @@ extern "C" {
void sbs_strcat(struct sbstring *sbs, const char *str);
void sbs_strncat(struct sbstring *sbs, const char *str, size_t size);
void sbs_strcpy(struct sbstring *sbs, const char *str);
void sbs_cut(struct sbstring *sbp, int bytes);
void sbs_substr(struct sbstring *sbp, ptrdiff_t pos, size_t len);
size_t sbs_length(const struct sbstring *sbs);
/* benchmark for units:

View File

@ -191,6 +191,45 @@ static void test_sbs_strcat(CuTest * tc)
CuAssertStrEquals(tc, "1234123", sbs.begin);
}
static void test_sbs_substr(CuTest * tc)
{
char buffer[10];
sbstring sbs;
buffer[9] = 'A';
sbs_init(&sbs, buffer, sizeof(buffer));
sbs_strcpy(&sbs, "12345678");
CuAssertStrEquals(tc, "12345678", buffer);
sbs_substr(&sbs, 0, 4);
CuAssertStrEquals(tc, "1234", buffer);
CuAssertIntEquals(tc, 4, (int)sbs_length(&sbs));
sbs_strcpy(&sbs, "12345678");
CuAssertStrEquals(tc, "12345678", buffer);
sbs_substr(&sbs, 4, 4);
CuAssertStrEquals(tc, "5678", buffer);
CuAssertIntEquals(tc, 4, (int)sbs_length(&sbs));
sbs_strcpy(&sbs, "12345678");
CuAssertStrEquals(tc, "12345678", buffer);
sbs_substr(&sbs, 2, 4);
CuAssertStrEquals(tc, "3456", buffer);
CuAssertIntEquals(tc, 4, (int)sbs_length(&sbs));
sbs_strcpy(&sbs, "12345678");
CuAssertStrEquals(tc, "12345678", buffer);
sbs_substr(&sbs, 4, 4);
CuAssertStrEquals(tc, "5678", buffer);
CuAssertIntEquals(tc, 4, (int)sbs_length(&sbs));
sbs_strcpy(&sbs, "12345678");
CuAssertStrEquals(tc, "12345678", buffer);
sbs_substr(&sbs, 4, 8);
CuAssertStrEquals(tc, "5678", buffer);
CuAssertIntEquals(tc, 4, (int)sbs_length(&sbs));
CuAssertIntEquals(tc, 'A', buffer[9]);
}
CuSuite *get_strings_suite(void)
{
CuSuite *suite = CuSuiteNew();
@ -205,5 +244,6 @@ CuSuite *get_strings_suite(void)
SUITE_ADD_TEST(suite, test_str_itoa);
SUITE_ADD_TEST(suite, test_sbstring);
SUITE_ADD_TEST(suite, test_sbs_strcat);
SUITE_ADD_TEST(suite, test_sbs_substr);
return suite;
}